changement du fichier tp scr

This commit is contained in:
2025-10-23 14:29:21 +02:00
parent fb76e22594
commit df89b08f5d
27 changed files with 0 additions and 0 deletions

BIN
TP_SCR3.1/TP_SIGNAUX/parexec Executable file

Binary file not shown.

View File

@@ -0,0 +1,36 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char* argv[])
{
// TODO
assert(argc >= 2);
// char prog = argv[1];
for(int i=2; i<argc; i++){
pid_t pid = fork();
if(pid == 0){
execlp(argv[1], argv[1], argv[i], NULL);
}
}
for(int i=2; i<argc; i++){
wait(NULL);
}
}

View File

@@ -0,0 +1,119 @@
/*
* parexec_lim.c
* Q3 : Lancer au plus N instances en parallèle : ./parexec_lim prog N arg1 [arg2 ...]
* Q4 : Si une instance se termine à cause d'un SIGNAL -> tuer toutes les autres et arrêter.
*/
#include <stdio.h> // fprintf, perror
#include <stdlib.h> // atoi, calloc, free, EXIT_*
#include <unistd.h> // fork, execlp, usleep
#include <sys/wait.h> // wait, WIFSIGNALED, WTERMSIG
#include <signal.h> // kill
#include <errno.h> // errno
int main(int argc, char *argv[]) {
// Vérifie la syntaxe minimale : prog + N + au moins 1 argument pour prog
if (argc < 4) {
fprintf(stderr, "Usage: %s prog N arg1 [arg2 ...]\n", argv[0]);
return EXIT_FAILURE;
}
char *prog = argv[1]; // le programme à lancer (ex: "./rebours")
int N = atoi(argv[2]); // nombre maximum d'enfants en parallèle
if (N <= 0) { // N doit être strictement positif
fprintf(stderr, "N doit être > 0\n");
return EXIT_FAILURE;
}
int next = 3; // index du prochain argument à donner à prog (argv[3] au début)
int running = 0; // nombre d'enfants actuellement en cours d'exécution
int stop = 0; // =1 si on a détecté une fin anormale -> on arrête de relancer
// Tableau des PIDs des enfants "actifs" (taille N). 0 signifie "case libre".
pid_t *slots = calloc((size_t)N, sizeof(pid_t));
if (!slots) { perror("calloc"); return EXIT_FAILURE; }
// ===== 1) Lancer tout de suite jusqu'à N enfants (ou jusqu'à épuisement des args) =====
while (!stop && running < N && next < argc) {
pid_t pid = fork(); // crée un nouveau processus
if (pid == 0) { // dans l'enfant
execlp(prog, prog, argv[next], NULL); // remplace l'enfant par "prog argi"
_exit(127); // si exec échoue, sortir avec code 127
}
if (pid < 0) { // fork a échoué dans le parent
perror("fork");
stop = 1; // on arrête les lancements
break;
}
// Ici on est dans le parent et fork a réussi : on mémorise le PID dans une case libre 2 5 4 3
for (int i = 0; i < N; ++i) {
if (slots[i] == 0) { // 0 = case libre
slots[i] = pid; // on range ce PID
break;
}
}
running++; // on a un enfant de plus
next++; // prochain argument à utiliser
}
// ===== 2) Boucle principale : attendre les fins, réagir, et (éventuellement) relancer =====
while (running > 0) { // tant qu'il reste des enfants actifs
int status = 0;
pid_t pid = wait(&status); // attendre qu'UN enfant se termine
if (pid < 0) { // erreur (souvent EINTR). On simplifie : on réessaie.
if (errno == EINTR){
continue;
}
perror("wait");
break;
}
// Retirer ce PID du tableau des actifs (libérer sa case)
for (int i = 0; i < N; ++i) {
if (slots[i] == pid) { // on a trouvé la case de cet enfant
slots[i] = 0; // on marque la case vide
break;
}
}
running--; // un enfant en moins
// ===== Q4 : si l'enfant s'est terminé à cause d'un SIGNAL =====
if (WIFSIGNALED(status)) {
stop = 1; // ne plus lancer de nouveaux enfants
// D'abord demander gentiment aux autres de s'arrêter
for (int i = 0; i < N; ++i) {
if (slots[i] > 0) kill(slots[i], SIGTERM);
}
usleep(100000); // petite pause (100 ms)
// Puis forcer l'arrêt si certains sont encore vivants
for (int i = 0; i < N; ++i) {
if (slots[i] > 0) kill(slots[i], SIGKILL);
}
// on n'ajoute PAS de relance ici (stop=1)
}
// ===== Relancer si : pas d'arrêt global ET il reste des arguments à lancer =====
if (!stop && next < argc) {
pid_t npid = fork(); // crée un nouvel enfant
if (npid == 0) { // dans le nouvel enfant
execlp(prog, prog, argv[next], NULL); // lance "prog arg"
_exit(127); // si exec échoue
}
if (npid < 0) { // fork a échoué
perror("fork");
stop = 1; // arrêter les relances
} else {
// ranger ce nouveau PID dans une case libre
for (int i = 0; i < N; ++i) {
if (slots[i] == 0) { slots[i] = npid; break; }
}
running++; // un enfant de plus en cours
next++; // passera à l'argument suivant lors de la prochaine relance
}
}
}
free(slots); // libérer la mémoire
if (stop) return 1; // échec
return 0; // succès
}

BIN
TP_SCR3.1/TP_SIGNAUX/rebours Executable file

Binary file not shown.

View File

@@ -0,0 +1,19 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
assert(argc == 2);
int value = strtol(argv[1], NULL, 0);
pid_t p = getpid();
printf("%d: debut\n",p);
for(int i = value; i>0; i--){
printf("%d: %d\n",p,i);
sleep(1);
}
printf("%d: fin\n",p);
return EXIT_SUCCESS;
}