changement du fichier tp scr
This commit is contained in:
BIN
TP_SCR3.1/TP_SIGNAUX/parexec
Executable file
BIN
TP_SCR3.1/TP_SIGNAUX/parexec
Executable file
Binary file not shown.
36
TP_SCR3.1/TP_SIGNAUX/parexec.c
Normal file
36
TP_SCR3.1/TP_SIGNAUX/parexec.c
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
119
TP_SCR3.1/TP_SIGNAUX/parexeclim.c
Normal file
119
TP_SCR3.1/TP_SIGNAUX/parexeclim.c
Normal 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
BIN
TP_SCR3.1/TP_SIGNAUX/rebours
Executable file
Binary file not shown.
19
TP_SCR3.1/TP_SIGNAUX/rebours.c
Normal file
19
TP_SCR3.1/TP_SIGNAUX/rebours.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user