getpid(),WIFSHSTOPPED(状态)检查子进程是否正在休眠

时间:2017-11-15 12:24:16

标签: c linux fork waitpid

您好我正在使用3个过程P0,P1,P2制作程序 我想做一个像下面的循环

init: P0 P1,P2 paused, signal to P0
P0 : wake up by signal -> finish job -> signal to P3 -> pause
P1 : wake up by signal -> finish job -> signal to P2 -> pause
P2 : wake up by signal -> finish job -> signal to P3 -> pause
repeat 0~2

不幸的是,SOMETIMES信号在目标进程睡眠之前出现

所以我想检查目标进程是否暂停。 我像这样插入[检查代码]

//end job here here
//
int status = 0;
do {
    waitpid(target_pid, &status, WNOHANG); // WNOHANG : check child status without waiting
} while ( ! WIFSTOPPED(status));           // linux man said that WIFSTOPPED
                                           // return true if process stopped
//signal to target_pid and pause() here

但它不起作用。

如果我使用

 while( ! WIFSTOPPED(status))

程序100%无法摆脱循环。

如果我使用

 while(   WIFSTOPPED(status))

它与我[检查代码]之前的工作方式相同

我知道waitpid函数用于检查进程结束。

但是不能waitpid()只是用于检查是否已被逮捕?

1 个答案:

答案 0 :(得分:0)

如果child完成normally(延迟结束后),那么您可以使用WIFEXITED(status),如果孩子已正常退出,则为真。

如果孩子从其他进程或同一进程获得killed(使用来自其他终端的kill命令)或被任何信号暂停,那么您可以使用WIFSIGNALED(status)

根据您的要求,我将您的代码修改为

int main()
{

        if(fork()==0) // p1
        {
                int t;
                srand(getpid());
                t = rand()%10 +1;//generating delay b/w 1 to 10 seconds
                printf("child1 delay : [%d] pid : [%d] ppid : [%d] \n",t,getpid(),getppid());
                sleep(t);
                printf("child1 pid : [%d] and its ppid : [%d] exiting \n",getpid(),getppid());
                exit(0);
        }
        else
        {
                if(fork()==0) // p2
                {
                        int t;
                        srand(getpid());
                        t = rand()%10 +1;//generating delay b/w 1 to 10 seconds
                        printf("child2 delay : [%d] pid : [%d] ppid : [%d] \n",t,getpid(),getppid());
                        sleep(t);
                        printf("child2 pid : [%d] and its ppid : [%d] exiting \n",getpid(),getppid());
                        exit(1);
                }
                else // p3
                {
                        int status;
                        printf("In parent...[%d]\n",getpid());
                        int ret;
                        while((ret = waitpid(-1,&status,0))!=-1)//when there is no child left it returns -1
                        {
                                if(WIFEXITED(&status))//if child is completed normally after sleep is over
                                {
                                        printf("child [%d] terminates normally : %d\n",ret,WEXITSTATUS(status));
                                }
                                if(WIFSIGNALED(&status))//true if child was killed by any signal from other process or same process
                                {
                                        printf("child [%d] terminates normally : %d\n",ret,WTERMSIG(status));//it will print the signal no by which it was killed
                                }
                        }
                }
        }
        return 0;
}

没有必要pause(),因为当一个进程被阻止,直到没有收到来自其他进程的信号时,你应该使用pause()

请浏览waitpid()的手册页。