Développement multi-process Linux



/*
#include
#include
pid_t fork(void);
Rôle : créer un processus enfant
valeur de retour :
La valeur de retour de fork() sera renvoyée deux fois, une fois dans le processus parent et une fois dans le processus fils
Renvoie l'ID du processus fils créé dans le processus père,
Dans le processus fils, retourne 0
Comment distinguer le processus père du processus fils, via la valeur de retour de fork
Retourne -1 dans le processus parent, indiquant que la création du processus enfant a échoué, et définit errno


La relation entre les processus parent et enfant :
la différence :
1. La valeur de retour de la fonction fork() est différente
Dans le processus parent : > 0, renvoie le PID du processus enfant
Dans le processus enfant :=0
2. Certaines données dans le pcb
id pid du processus en cours
L'id ppid du parent procession du processus en cours
Signal défini
Base commune :
Dans certains états, le processus enfant vient d'être créé et n'a pas encore effectué d'opérations d'écriture de données
- Données de la zone utilisateur
- table des descripteurs de fichiers
Si les processus parents et enfants partagent des variables
-C'est pareil au début, si vous modifiez les données de la classe, elles ne seront pas partagées
Partage- en lecture (processus enfant venant d'être créé), copie en écriture
Les variables ne peuvent pas être utilisées pour communiquer entre les processus parent et enfant, elles ne s'affectent pas les unes les autres

< span style="color:rgba(0,128,0,1);">*/
#include < /span>
#include

#include

int main()
{

int< /span> num =10;
//创建子进程
pid_t pid = fork();//pid_t本质上是int类型的
//判断是父进程还是子进程
if(pid>0){
printf(
"pid : %d\
", pid);
//如果大于0,返回的是创建的子进程的id,当前是父进程
printf("i am parent process,pid : %d, ppid :%d\
",getpid(),getppid());
printf(
"numéro parent : %d\
",num);
nombre
+=10;
printf(
"numéro parent+=10 : %d\
",num);
}
autre si(pid == 0)
{
//当前是子进程
printf("je suis un enfant processus, pid :%d,ppid : %d\
",getpid(),getppid());
printf(
"numéro enfant : %d\
",num);
nombre span>+=100;
printf(
"numéro enfant+=100 : %d\
",num);
}
pour (int je =0< /span>;i<3;i++)//执行
{
printf(
"je : %d\
", je);
dormir(
1 );

}
retour 0;
}



famille de fonctions exec


La zone utilisateur du fichier exécutable remplace la zone utilisateur dans le processus. Généralement, un processus enfant sera créé et les fonctions de la famille de fonctions exec seront créées dans le processus enfant.




Afficher l'exécution



Sous-processusest remplacé


execlp

/*#include &lt ;unistd. h>

extern char **environ;

int execlp(const char *file, const char *arg, ...);
- Cela ressemblera pour le fichier exécutable spécifié dans la variable d'environnement. S'il est trouvé, il sera exécuté, et s'il n'est pas trouvé, il sera exécuté.
Paramètres : -file : Le nom du fichier exécutable à spécifier pour l'exécution
a.out ps
-arg : est la liste des arguments nécessaires pour exécuter l'exécutable
Le premier paramètre n'a généralement aucun effet. Afin de faciliter l'écriture du nom du paramètre en général, à partir du deuxième paramètre, il s'agit de la liste des paramètres nécessaires à l'exécution du programme.
Les arguments doivent se terminer par NULL à la fin (sentry)
Valeur de retour : -Retourner uniquement en cas d'erreur, renvoyer -1 et définir errno
Si l'appel réussit, ilis no return value

*/
#include

#include


int main()
{
//创建一个子进程在子进程中执行exec函数族中的函数

pid_t pid
=fork();
if(pid >0){
//父进程
printf("i am parent process,pid : %d\
",getpid());
sleep(
1 );
}
autrement si(pid == 0)
{
//子进程
execlp("ps","ps","aux",NULL);
printf(
"je suis un processus enfant, pid :%d\
"< /span>,getpid());
}
for(int< /span> i =0;i<3;i++){
printf(
"< span style="color:rgba(128,0,0,1);">i =%d , pid = %d\
",i,getpid());
}
< br />
retour 0< /span> span>;
}


Le premier paramètre est le nom du programme du programme exécutable, le deuxième paramètre


Contrôle de processus


La fonction fork partage lors de la lecture, copie lors de l'écriture Le but principal est de réduire l'utilisation de la mémoire



Lorsque le processus enfant se termine, le processus parent peut obtenir le statut de sortie du processus enfant Le processus parent est obligé de recycler les ressources du processus enfant



#include
#include

#include

int main()
{
printf(
" span>bonjour \
") ;
printf(
"monde ");

sortie(
0) ;

retour 0 étendue> ; //Identique à exit, les deux indiquent que le processus se termine

}


Résultat exit() On peut le voir à partir de la comparaison des fonctions des deux dans la figure

Remplacez exit() par _exit() world is in the buffer


Processus orphelin


Le processus parent est terminé et le processus enfant est toujours en cours d'exécution, un tel processus enfant est appelé un processus orphelin
? Chaque fois qu'un processus orphelin se produit, le noyau définit le processus parent du processus orphelin sur init, et le processus init attend cycliquement() son processus enfant quittant. De cette façon, lorsqu'un processus orphelin termine sombrement son cycle de vie, l'init process s'occupe de toutes les conséquences en son nom.
Les processus orphelins ne sont pas nocifs
Comme suit, 1 a adopté le processus orphelin et 1 a récupéré des ressources


Une fois le processus parent terminé, un terminal s'affiche (retour au premier plan)
Pourquoi sont tous affichés dans le terminal ? Certaines parties du noyau des processus parent et enfant sont partagées Les trois premiers (0, 1, 2) de la table des descripteurs de fichiers (0, 1, 2) entrée standard, sortie, erreur

Processus zombie


? À la fin de chaque processus, il libère les données de la zone utilisateur dans son propre espace d'adressage. Le PCB dans la zone du noyau ne peut pas être libéré par lui-même et le processus parent doit le libérer.
 ? Lorsque le processus se termine, le processus parent n'a pas récupéré et les ressources résiduelles (PCB) du processus enfant sont stockées dans le noyau et deviennent un processus zombie
(Zombie).
Le processus zombie ne peut pas être tué par kii -9

Linux muDéveloppement de lti-procédés