C forks and processes,“为什么需要这个?
C forks and processes, ¿Why its necessary this?
我是学C的,一直在尝试做一个简单的测试程序。问题是我有一个问题是通过我不理解的方式解决的。这是我的程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
void trat1(int s){
signal(SIGALRM, trat1);
}
void trat2(int s){
signal(SIGALRM, trat2);
}
int main( void ) {
int statusHijo1, statusHijo2;
int hijo1, hijo2;
int hijoFinalizado, status;
statusHijo1 =0;
statusHijo2 = 0;
if((hijo1 = fork()) == 0){
/* Hijo 1 */
printf("-- Hijo1 PID:%d | Parent PID:%d", getpid(), getppid());
printf("\n -- Hijo1 Lanzando SIGTERM -- \n");
while(1){
signal(SIGALRM, trat2);
alarm(1);
pause();
printf(" -- Hijo1 awaitting 1 sec.. \n");
}
}
else{
if ( (hijo2=fork()) == 0 ) {
/* Hijo 2 */
printf("++ Hijo2 PID:%d | Parent PID:%d \n", getpid(), getppid());
signal(SIGALRM, trat2);
alarm(5);
pause();
kill(hijo1, SIGKILL);
printf("++ Hijo2 Sending Kill signal to Hijo1\n");
printf("++ Proceso Hijo2 terminado\n");
}
else{
/* Padre */
do{
hijoFinalizado = wait(&status); //El hijo finalizado es el que cambia el estado del programa
if(hijoFinalizado == hijo1) statusHijo1 = 1;
else if(hijoFinalizado == hijo2) statusHijo2 = 1;
}while(!statusHijo1 || !statusHijo2);
printf("\n** Soy el padre con PID: %d y he terminado \n", getpid());
}
}
}
这个程序很简单,父亲在等他的两个孩子,1会等5秒,直到第二个杀死它。
这里是控制台的输出:
-- Hijo1 PID:29793 | Parent PID:29792
-- Hijo1 Lanzando SIGTERM --
++ Hijo2 PID:29794 | Parent PID:29792
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
** Soy el padre con PID: 29792 y he terminado
问题是我不知道 hijoFinalizado = wait(&status);
是如何工作的,因为没有它程序就无法运行。
这是没有它的情况:
-- Hijo1 PID:1547 | Parent PID:1546
-- Hijo1 Lanzando SIGTERM --
++ Hijo2 PID:1548 | Parent PID:1546
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
然后卡在这里。
¿为什么我没有声明的变量是决定进程是否完成的变量?
¿ 为什么 while( (wait(&statusHijo1)!=hijo1)&& (wait(&statusHijo2)!=hijo2) ) ;
不正确?
这是这样做的结果:
-- Hijo1 PID:1148 | Parent PID:1147
++ Hijo2 PID:1149 | Parent PID:1147
-- Hijo1 Lanzando SIGTERM --
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
然后卡在这里。
[加法]
¿trat1 和 trat2 的真正功能是什么?我知道它们很重要,但我不知道为什么。
对不起我的英语,非常感谢。
Why a variable that I dont declare is the one who decides if a process has finished?
你是说status
?你声明它;你只是不初始化它。这很好,因为 wait
不读它; wait
填充它。换句话说,它不是输入;这是一个输出。
wait
等待 child 完成。它 returns 进程的 PID,并将 status
设置为 child 的退出状态。
您可以使用状态如下:
if (WIFSTOPPED(status)) {
printf("Child killed by signal %d\.n", WSTOPSIG(status));
}
else if (WEXITSTATUS(status)) {
printf("Child exited with error %d.\n", WEXITSTATUS(status));
}
else {
printf("Child completed successfully.\n", WEXITSTATUS(status));
}
仅回答附加问题
实施
while( (wait(&statusHijo1)!=hijo1)&& (wait(&statusHijo2)!=hijo2) ) ;
是错误的,因为您不能 wait
仅针对特定的 child。 (为此您需要 waitpid
,但您必须确保在您的代码中指定的 child 能够终止。)
您可以遍历代码并思考会发生什么。
示例:
假设 child 1 在 child 2 之前终止。
第一个wait(&statusHijo1)
将child1的状态保存到statusHijo1
,returnchild1的PID和条件!=hijo1
将为假。
作为逻辑与的结果,所以不会调用第二个wait(&statusHijo2)
而终止循环。你的程序不会等待child2,statusHijo2
不变。
假设 child 2 在 child 1 之前终止。
第一个wait(&statusHijo1)
将child2的状态保存到statusHijo1
,returnchild2的PID和条件!=hijo1
将为真,因此它将调用第二个 wait(&statusHijo2)
。
这会将 child 1 的状态保存到 statusHijo2
,return child 1 的 PID,并且条件 !=hijo2
将为真。
循环将重复,因为两个条件都为真。
它将再次调用 wait(&statusHijo1)
,这将 return -1 因为您没有 child 等待。条件 !=hijo1
将为真,它将调用 wait(&statusHijo2)
, return -1 并且条件 !=hijo2
将为真,因此它将再次重复循环。
在这种情况下你会得到一个无限循环。
trat1
和 trat2
是 SIGALRM
的信号处理函数。他们只做 re-establish 自己。 signal()
的实现因不同的 UNIX 系统而异。在某些系统上,接收信号会将信号处理程序重置为默认值,因此信号处理程序必须再次调用 signal()
。
没有信号处理程序,信号 SIGALRM
将终止进程。
代替signal(SIGALRM, trat2); alarm(5); pause();
你也可以使用sleep(5);
.
我是学C的,一直在尝试做一个简单的测试程序。问题是我有一个问题是通过我不理解的方式解决的。这是我的程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
void trat1(int s){
signal(SIGALRM, trat1);
}
void trat2(int s){
signal(SIGALRM, trat2);
}
int main( void ) {
int statusHijo1, statusHijo2;
int hijo1, hijo2;
int hijoFinalizado, status;
statusHijo1 =0;
statusHijo2 = 0;
if((hijo1 = fork()) == 0){
/* Hijo 1 */
printf("-- Hijo1 PID:%d | Parent PID:%d", getpid(), getppid());
printf("\n -- Hijo1 Lanzando SIGTERM -- \n");
while(1){
signal(SIGALRM, trat2);
alarm(1);
pause();
printf(" -- Hijo1 awaitting 1 sec.. \n");
}
}
else{
if ( (hijo2=fork()) == 0 ) {
/* Hijo 2 */
printf("++ Hijo2 PID:%d | Parent PID:%d \n", getpid(), getppid());
signal(SIGALRM, trat2);
alarm(5);
pause();
kill(hijo1, SIGKILL);
printf("++ Hijo2 Sending Kill signal to Hijo1\n");
printf("++ Proceso Hijo2 terminado\n");
}
else{
/* Padre */
do{
hijoFinalizado = wait(&status); //El hijo finalizado es el que cambia el estado del programa
if(hijoFinalizado == hijo1) statusHijo1 = 1;
else if(hijoFinalizado == hijo2) statusHijo2 = 1;
}while(!statusHijo1 || !statusHijo2);
printf("\n** Soy el padre con PID: %d y he terminado \n", getpid());
}
}
}
这个程序很简单,父亲在等他的两个孩子,1会等5秒,直到第二个杀死它。
这里是控制台的输出:
-- Hijo1 PID:29793 | Parent PID:29792
-- Hijo1 Lanzando SIGTERM --
++ Hijo2 PID:29794 | Parent PID:29792
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
** Soy el padre con PID: 29792 y he terminado
问题是我不知道 hijoFinalizado = wait(&status);
是如何工作的,因为没有它程序就无法运行。
这是没有它的情况:
-- Hijo1 PID:1547 | Parent PID:1546
-- Hijo1 Lanzando SIGTERM --
++ Hijo2 PID:1548 | Parent PID:1546
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
然后卡在这里。
¿为什么我没有声明的变量是决定进程是否完成的变量?
¿ 为什么 while( (wait(&statusHijo1)!=hijo1)&& (wait(&statusHijo2)!=hijo2) ) ;
不正确?
这是这样做的结果:
-- Hijo1 PID:1148 | Parent PID:1147
++ Hijo2 PID:1149 | Parent PID:1147
-- Hijo1 Lanzando SIGTERM --
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
-- Hijo1 awaitting 1 sec..
++ Hijo2 Sending Kill signal to Hijo1
++ Proceso Hijo2 terminado
然后卡在这里。
[加法]
¿trat1 和 trat2 的真正功能是什么?我知道它们很重要,但我不知道为什么。
对不起我的英语,非常感谢。
Why a variable that I dont declare is the one who decides if a process has finished?
你是说status
?你声明它;你只是不初始化它。这很好,因为 wait
不读它; wait
填充它。换句话说,它不是输入;这是一个输出。
wait
等待 child 完成。它 returns 进程的 PID,并将 status
设置为 child 的退出状态。
您可以使用状态如下:
if (WIFSTOPPED(status)) {
printf("Child killed by signal %d\.n", WSTOPSIG(status));
}
else if (WEXITSTATUS(status)) {
printf("Child exited with error %d.\n", WEXITSTATUS(status));
}
else {
printf("Child completed successfully.\n", WEXITSTATUS(status));
}
仅回答附加问题
实施
while( (wait(&statusHijo1)!=hijo1)&& (wait(&statusHijo2)!=hijo2) ) ;
是错误的,因为您不能 wait
仅针对特定的 child。 (为此您需要 waitpid
,但您必须确保在您的代码中指定的 child 能够终止。)
您可以遍历代码并思考会发生什么。
示例:
假设 child 1 在 child 2 之前终止。
第一个wait(&statusHijo1)
将child1的状态保存到statusHijo1
,returnchild1的PID和条件!=hijo1
将为假。
作为逻辑与的结果,所以不会调用第二个wait(&statusHijo2)
而终止循环。你的程序不会等待child2,statusHijo2
不变。
假设 child 2 在 child 1 之前终止。
第一个wait(&statusHijo1)
将child2的状态保存到statusHijo1
,returnchild2的PID和条件!=hijo1
将为真,因此它将调用第二个 wait(&statusHijo2)
。
这会将 child 1 的状态保存到 statusHijo2
,return child 1 的 PID,并且条件 !=hijo2
将为真。
循环将重复,因为两个条件都为真。
它将再次调用 wait(&statusHijo1)
,这将 return -1 因为您没有 child 等待。条件 !=hijo1
将为真,它将调用 wait(&statusHijo2)
, return -1 并且条件 !=hijo2
将为真,因此它将再次重复循环。
在这种情况下你会得到一个无限循环。
trat1
和 trat2
是 SIGALRM
的信号处理函数。他们只做 re-establish 自己。 signal()
的实现因不同的 UNIX 系统而异。在某些系统上,接收信号会将信号处理程序重置为默认值,因此信号处理程序必须再次调用 signal()
。
没有信号处理程序,信号 SIGALRM
将终止进程。
代替signal(SIGALRM, trat2); alarm(5); pause();
你也可以使用sleep(5);
.