pid_t getpid();
pid_t getppid();
Voici un exemple de programme affichant son PID et son PPID:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char**argv) {
("Current process ID: %d\n", getpid());
printf("Current parent process ID: %d\n", getppid());
printfreturn EXIT_SUCCESS;
}
Ce programme donne pour résultat:
$ ./print_id
Current process ID: 17174
Current parent process ID: 25275
Lorsque le processus parent (P1
) d’un processus
(P2
) meurt, le processus fils est rattaché au processus au
processus initial de PID 1. Le PPID de P2
devient donc
1.
int system(const char* cmd);
cmd
Voici un exemple de programme utilisant la fonction
system
:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char**argv) {
int ret_val;
char* cmd="ps f";
("Running command '%s'\n", cmd);
printf("-----------\n");
printf= system(cmd);
ret_val ("-----------\n");
printf("system returned %d\n", ret_val);
printfreturn EXIT_SUCCESS;
}
Ce programme donne pour résultat:
$ ./system
Running command 'ps f'
-----------
PID TTY STAT TIME COMMAND
16847 pts/1 Ss+ 0:00 bash
17076 pts/1 S 0:01 _ okular chap.pdf
8199 pts/0 Ss+ 0:00 bash
25275 pts/7 Ss 0:00 bash
8174 pts/7 Sl 0:14 _ emacs contenu.tex
17540 pts/7 S+ 0:00 _ ./system
17541 pts/7 S+ 0:00 _ sh -c ps f
17542 pts/7 R+ 0:00 _ ps f
-----------
system returned 0
pid_t fork();
Voici un exemple d’utilisation de fork
:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char**argv) {
("I am process %d. My PPID: %d\n", getpid(), getppid());
printf
= fork();
pid_t ret_val if(ret_val == 0) {
("I'm the child process. PID=%d, PPID=%d\n", getpid(), getppid());
printf(1);
sleep} else if (ret_val>0) {
("I'm the parent process. PID=%d, PPID=%d\n", getpid(), getppid());
printf} else {
("Fork failed\n");
printf}
return EXIT_SUCCESS;
}
Lors du fork
, le processus est intégralement dupliqué.
Le processus fils possède donc la même mémoire que le processus père: on
retrouve donc les variables affectées dans le processus père avant le
fork.
Après le fork, les espaces mémoire des deux processus deviennent
dissociés: si le processus fils (resp. le père) modifie la variable
value
, il ne modifie que sa copie de la variable, et le
processus père (resp. le fils) ne voit pas la modification. Par exemple,
le programme suivant:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char**argv) {
int value = 1;
("[%d] Before forking. value = %d\n", getpid(), value);
printf= fork();
pid_t ret_val if(ret_val == 0) {
++;
value("[%d] After forking. value = %d\n", getpid(), value);
printf} else if (ret_val>0) {
(1);
sleep("[%d] After forking. value = %d\n", getpid(), value);
printf} else {
("Fork failed\n");
printf}
return EXIT_SUCCESS;
}
donnera, lors de son exécution, le résultat suivant:
$ ./fork_variable
[13229] Before forking. value = 1
[13230] After forking. value = 2
[13229] After forking. value = 1
exec
execlp
, execvp
, execve
,
execle
, execlp
, etc.Voici un exemple d’utilisation de execlp
:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char**argv) {
("I am process %d. My PPID: %d\n", getpid(), getppid());
printf
= fork();
pid_t ret_val if(ret_val == 0) {
("I'm the child process. PID=%d, PPID=%d\n", getpid(), getppid());
printf("ps", "ps", "-l", NULL);
execlp("This is printed only if execlp fails\n");
printf();
abort} else if (ret_val>0) {
("I'm the parent process. PID=%d, PPID=%d\n", getpid(), getppid());
printf(1);
sleep}
return EXIT_SUCCESS;
}
exec
est une famille de fonction permettant de remplacer
l’image du processus courant: l’ensemble de l’espace mémoire est effacé
et remplacé par l’image du procegramme exécuté.
Les paramètres peuvent être passés sous la forme d’une liste de
paramètres (avec les fonctions execl*
), ou sous la forme
d’un tableau de chaînes de caractères (avec les fonctions
execv*
).
pid_t wait(int *status);
status
permet de connaître la cause du
décès.pid_t waitpid(pid_t pid, int *wstatus, int options);
Voici un exemple d’utilisation de la fonction wait
:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char**argv) {
("I am process %d. My PPID: %d\n", getpid(), getppid());
printf
= fork();
pid_t ret_val if(ret_val == 0) {
("I'm the child process. PID=%d, PPID=%d\n", getpid(), getppid());
printf(1);
sleepreturn 17;
} else if (ret_val>0) {
("I'm the parent process. PID=%d, PPID=%d\n", getpid(), getppid());
printfint status;
= wait(&status);
pid_t pid
int exit_status = WEXITSTATUS(status);
("The child process %d ended with exit status %d\n", pid, exit_status);
printf
} else {
("Fork failed\n");
printf}
return EXIT_SUCCESS;
}
La fonction wait
retourne le PID du processus fils qui
s’est terminé et remplit la variable entière status
. Cette
variable peut ensuite être utilisée pour obtenir des informations sur la
terminaison du processus fils.
Par exemple, la macro WEXITSTATUS(status)
retourne le
code de retour du processus fils. Ce programme donnera donc :
$ ./exemple_wait
I am process 21088. My PPID: 20960
I'm the parent process. PID=21088, PPID=20960
I'm the child process. PID=21089, PPID=21088
The child process 21089 ended with exit status 17
La fonction waitpid
est une variante de
wait
. Elle permet d’attendre un processus fils précis, ou
de tester (sans bloquer le processus appelant) la terminaison d’un
processus.