Truca al sistema de forquilla en C.

Fork System Call C



La trucada del sistema fork () s'utilitza per crear processos fills en un programa C. fork () s'utilitza quan es requereix un processament paral·lel a la vostra aplicació. La funció del sistema fork () es defineix a les capçaleres sys / types.h i unistd.h . En un programa on utilitzeu fork, també heu d'utilitzar la trucada de sistema wait (). La trucada de sistema wait () s'utilitza per esperar al procés pare fins que finalitzi el procés fill. Per acabar un procés secundari, s’utilitza la trucada del sistema exit () al procés secundari. La funció wait () es defineix a la capçalera sys / wait.h i la funció exit () es defineix a la capçalera stdlib.h .

Fig 1: flux de treball bàsic fork ()

Fig 1: flux de treball bàsic fork ()







En aquest article, us mostraré com utilitzar la trucada del sistema fork () per crear processos secundaris a C. Per tant, comencem.



fork () Sintaxi i valor de retorn:

La sintaxi de la funció del sistema fork () és la següent:



pid_t bifurcació(buit);

La funció del sistema fork () no accepta cap argument. Retorna un enter del tipus pid_t .





Si té èxit, fork () retorna el PID del procés fill que és superior a 0. Dins del procés fill, el valor de retorn és 0. Si fork () falla, torna -1.

Forquilla simple () Exemple:

A continuació es mostra un exemple simple de fork ():



#incloure
#incloure
#incloure
#incloure
#incloure

intprincipal(buit) {
pid_t pid=forquilla();

si(pid== 0) {
printf ('Nen => PPID:% d PID:% d n',getppid(),getpid());
sortir (SORTIR_ÈXIT);
}
en cas contrari si(pid> 0) {
printf ('Parent => PID:% d n',getpid());
printf ('Esperant que finalitzi el procés infantil. n');
espera(NUL);
printf ('S'ha acabat el procés fill. n');
}
en cas contrari {
printf ('No s'ha pogut crear el procés fill. n');
}

tornarSORTIR_ÈXIT;
}

Aquí, he utilitzat fork () per crear un procés fill a partir del procés principal / pare. A continuació, vaig imprimir el PID (ID de procés) i PPID (ID de procés pare) del procés fill i pare. En el procés principal, l'espera (NULL) s'utilitza per esperar a que finalitzi el procés fill. En el procés fill, exit () s’utilitza per acabar el procés fill. Com podeu veure, el PID del procés pare és el PPID del procés fill. Per tant, el procés infantil 24738 pertany al procés principal 24.731 .

També podeu utilitzar funcions per fer que el vostre programa sigui més modular. Aquí, he utilitzat processTask () i parentTask () funcions per als processos fill i pare respectivament. Així s’utilitza realment fork ().

#incloure
#incloure
#incloure
#incloure
#incloure

buitchildTask() {
printf ('Hola món n');
}

buittasca parental() {
printf ('Tasca principal. n');
}

intprincipal(buit) {
pid_t pid=forquilla();

si(pid== 0) {
childTask();
sortir (SORTIR_ÈXIT);
}
en cas contrari si(pid> 0) {
espera(NUL);
tasca parental();
}
en cas contrari {
printf ('No es pot crear el procés secundari.');
}

tornarSORTIR_ÈXIT;
}

La sortida del programa anterior:

Execució de diversos processos secundaris mitjançant fork () i Loop:

També podeu utilitzar bucle per crear tants processos secundaris com necessiteu. A l'exemple següent, he creat 5 processos fills amb el bucle for. També he imprès el PID i el PPID dels processos secundaris.

#incloure
#incloure
#incloure
#incloure
#incloure

intprincipal(buit) {
per(intjo= 1;jo<= 5;jo++) {
pid_t pid=forquilla();

si(pid== 0) {
printf ('Procés fill => PPID =% d, PID =% d n',getppid(),getpid());
sortir (0);
}
en cas contrari {
printf ('Procés pare => PID =% d n',getpid());
printf ('Esperant que acabin els processos fills ... n');
espera(NUL);
printf ('procés fill acabat. n');
}
}

tornarSORTIR_ÈXIT;
}

Com podeu veure, l’identificador de procés principal és el mateix en tots els processos secundaris. Per tant, tots pertanyen al mateix pare. També s’executen de manera lineal. Un darrere l’altre. El control de processos fills és una tasca sofisticada. Si obteniu més informació sobre la programació del sistema Linux i el seu funcionament, podreu controlar el flux d’aquests processos com vulgueu.

Exemple de la vida real:

Diferents càlculs matemàtics complexos com la generació de hash md5, sha256, etc. requereixen molta potència de processament. En lloc de computar coses així en el mateix procés que el programa principal, podeu calcular el hash d’un procés fill i tornar el hash al procés principal.

A l’exemple següent, he generat un codi PIN de 4 dígits en un procés secundari i l’he enviat al procés principal, el programa principal. Després, vaig imprimir el codi PIN des d’allà.

#incloure
#incloure
#incloure
#incloure
#incloure

intgetPIN() {
// utilitzeu PPID i PID com a llavor
srand (getpid() +getppid());
intsecret= 1000 + fila () % 9000;
tornarsecret;
}

intprincipal(buit) {
intfd[2];
canonada(fd);
pid_t pid=forquilla();

si(pid> 0) {
Tanca(0);
Tanca(fd[1]);
després(fd[0]);

intnúmero secret;
mida_treadBytes=llegir(fd[0], &número secret, mida de(número secret));

printf ('S'està esperant el PIN ... n');
espera(NUL);
printf ('Bytes llegits:% ld n',readBytes);
printf (PIN:% d n',número secret);
}
en cas contrari si(pid== 0) {
Tanca(1);
Tanca(fd[0]);
després(fd[1]);

intsecret=getPIN();
escriure(fd[1], &secret, mida de(secret));
sortir (SORTIR_ÈXIT);
}

tornarSORTIR_ÈXIT;
}

Com podeu veure, cada cop que executo el programa, rebo un codi PIN de 4 dígits diferent.

Per tant, bàsicament és com s’utilitza la trucada al sistema fork () a Linux. Gràcies per llegir aquest article.