C,得到一个父和子进程使用的信号工作 [英] C, getting a parent and child process to work using signals

查看:223
本文介绍了C,得到一个父和子进程使用的信号工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我的子进程产生1-9之间的随机数,然后将其发送给它就会显示它筛选每个时间控制+ Z我的父进程是pressed。我还使用dup2()从printf和scanf的流改变为读和写管道的端部的每个处理。

在code运行情况如下,你preSS控制C以启动主程序。现在它等待控制Z到是pssed每一个随机数被从子发出并在父显示的时间为$ P $。我现在面临的问题是,似乎孩子只运行的一次:当控制Z是pressed再次,它只能运行在父code。管也只会显示了相同的编号,并不会改变,以便其不被更新。我也注意到,如果我删除线的printf dup函数之前的的printf(一个\\ n),它打印出随机数....但是随着孩子一旦运行仍存在的问题。

应该AP preciate如果有人可以帮助我在此。干杯。

 的#include<&stdio.h中GT;
#包括LT&;&signal.h中GT;
#包括LT&;&fcntl.h GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&time.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&stdlib.h中GT;INT选择= 0;
INT secondSel = 0;
INT FD [2];
INT PIPE1;
将为pid_t与fork1;无效handleSignal(INT SIG)
{
  如果(SIG == SIGINT)
    {
      选择= 1;
      secondSel = 1;
    }
  如果(SIG == SIGTSTP)
    {
      选择= 1;
    }
}诠释的main()
{
INT firstPipe [2];
  INT secondPipe [2];//等待控制+ C
  如果(信号(SIGINT,handleSignal)== SIG_ERR)
    {
    的printf(错误捕获信号C \\ n);
    出口(0);
    }  而(1)
    {
      //等到控制c是pressed
      如果(选择== 1)
    {
      信号(SIGINT,SIG_IGN);      如果(secondSel == 1)
        {
          PIPE1 =管(FD);
        }
      如果(PIPE1℃,)
        {
          的printf(错误创建管1 \\ n);
          出口(1);
        }      如果(secondSel == 1)
        {
          与fork1 = fork()的;
        }
      如果(与fork1℃,)
        {
          的printf(错误与第一叉\\ n);
          出口(1);
        }
      否则,如果(与fork1 == 0)//第一子进程
        {
          信号(SIGTSTP,handleSignal);
          暂停();
          的printf(A \\ n);
          INT randNum1;
          关闭(FD [0]);
          dup2(FD [1],1);
          randNum1 =兰特()%9 + 1;          的printf(%D,randNum1);
          fflush(标准输出);
          关闭(FD [1]);
        }
      别的家长//
        {
          信号(SIGTSTP,handleSignal);
          暂停();
          的printf(B \\ n);
          INT F;
          关闭(FD [1]);
          dup2(FD [0],0);
          scanf函数(%d个\\ n,&安培; F);
          的printf(%d个\\ N,F);
          关闭(FD [0]);
        }
      secondSel = 0;
    }
    }}


解决方案

注释/ code:

  //等待控制+ C
如果(信号(SIGINT,handleSignal)== SIG_ERR)

是一个令人不安的开始。在信号()函数设置为 SIGINT 信号处理程序,但它没有办法等待信号的到来。对于最简单的解决方法是添加一个调用 暂停( ) 后code的该块。

在无限循环中,code:

 如果(secondSel == 1)
        {
            PIPE1 =管(FD);
        }
        如果(PIPE1℃,)
        {
            的printf(错误创建管1 \\ n);
            出口(1);
        }

是次优的和/或混乱。由于 PIPE1 管道()被调用时,就没有必要测试它在每次迭代时,才设置。错误信息应报告在标准错误,不应该有尾随空白。在code应该是:

 如果(secondSel == 1)
        {
            如果(管道(FD)℃,)
            {
                fprintf中(标准错误,错误创建管1 \\ n);
                出口(1);
            }
        }

有一个在同一个变量进行类似的测试保护叉()

您code小心关闭的第一个周期后的管,但从来没有重新打开它。这就是最终为什么在第二和随后的迭代失败。您code会更好,如果你没有尝试做每个周期的一切。此外,使用标准输出的调试信息是受到各种问题;最好是使用标准的错误,而不是 - 尤其是在标准输出不能正常工作

仪器化code

这是你的code的Instrumented版本。在 err_syserr()函数几乎是通用的;使用 usleep()函式的条件所特有的这种code和确保终止错误信息的输出通常测序。我把函数调用,将被失败试验 - 第一关闭失败在第二周期,因为管道描述符全部关闭在第一循环结束。 (请注意,重用管道()后叉没有帮助() - 在家长和孩子会管不连接到彼此。)

 的#include<&signal.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;静态无效err_syserr(为const char * FMT,...);INT选择= 0;
INT secondSel = 0;
INT FD [2];
INT PIPE1 = 0;
将为pid_t与fork1 = 0;静态无效handleSignal(INT SIG)
{
    如果(SIG == SIGINT)
    {
        选择= 1;
        secondSel = 1;
    }
    如果(SIG == SIGTSTP)
    {
        选择= 1;
    }
}INT主要(无效)
{
    //等待控制+ C
    如果(信号(SIGINT,handleSignal)== SIG_ERR)
    {
        的printf(错误捕获信号C \\ n);
        出口(1);
    }
    //输出(等待中断\\ n);
    //暂停();    而(1)
    {
        fprintf中(标准错误,循环:%D(%D)\\ n,(INT)GETPID(),选择);
        //等到控制c是pressed
        如果(选择== 1)
        {
            信号(SIGINT,SIG_IGN);            如果(secondSel == 1)
            {
                PIPE1 =管(FD);
                fprintf中(标准错误,创建的管道:%D(%D,%D)\\ n,PIPE1,FD [0],FD [1]);
            }
            如果(PIPE1℃,)
            {
                的printf(错误创建管1 \\ n);
                出口(1);
            }            如果(secondSel == 1)
            {
                与fork1 = fork()的;
                fprintf中(标准错误,叉形:%D(%D,%D)\\ n,与fork1(INT)GETPID(),(INT)getppid());
            }            如果(与fork1℃,)
            {
                的printf(错误与第一叉\\ n);
                出口(1);
            }
            否则,如果(与fork1 == 0)//第一子进程
            {
                信号(SIGTSTP,handleSignal);
                fprintf中(标准错误,暂停C:%d个\\ N(INT)GETPID());
                暂停();
                fprintf中(标准错误,取消暂停C:%d个\\ N(INT)GETPID());
                的printf(A \\ n);
                如果(接近(FD [0])!= 0)
                    err_syserr(关闭(FD [0] =%d)失败,FD [0]);
                如果(dup2(FD [1],1) - = 0)
                    err_syserr(dup2(FD [1] =%d个,1)失败,FD [1]);
                INT randNum1 =兰特()%9 + 1;                fprintf中(标准错误,打印C:%d个\\ N,randNum1);
                如果(的printf(%d个\\ N,randNum1)2)
                {
                    fprintf中(标准错误,打印C:失败\\ n);
                    的clearerr(标准输出);
                }
                fflush(标准输出);
                如果(接近(FD [1])!= 0)
                    err_syserr(关闭(FD [1] =%d)失败,FD [1]);
            }
            别的家长//
            {
                信号(SIGTSTP,handleSignal);
                fprintf中(标准错误,暂停病人:%d个\\ N(INT)GETPID());
                暂停();
                fprintf中(标准错误,取消暂停病人:%d个\\ N(INT)GETPID());
                的printf(B \\ n);
                如果(接近(FD [1])!= 0)
                    err_syserr(关闭(FD [1] =%d)失败,FD [1]);
                如果(dup2(FD [0],0)℃的)
                    err_syserr(dup2(FD [0] =%d个,0)失败,FD [0]);
                INT F = 99;
                如果(scanf的(%d个,&放大器;!F)= 1)
                {
                    fprintf中(标准错误,scanf的病人:失败\\ n);
                    的clearerr(标准输入);
                }
                的printf(父数:%d \\ n,F);
                如果(接近(FD [0])℃的)
                    err_syserr(关闭(FD [0] =%d)失败,FD [0]);
            }
            secondSel = 0;
        }
    }
    返回0;
}#包括LT&;&errno.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&STDARG.H GT;静态无效err_syserr(为const char * FMT,...)
{
    INT的差错编号= errno的;
    va_list的ARGS;
    如果(与fork1!= 0)/ *家长等待1/4秒* /
        usleep(250000);
    fprintf中(标准错误,%D:(INT)GETPID());
    的va_start(参数,FMT);
    vfprintf(标准错误,格式化,参数);
    va_end用来(参数);
    如果(差错编号!= 0)
        fprintf中(标准错误,数:%d%S,差错编号,字符串错误(差错编号));
    的fputc('\\ n',标准错误);
    出口(EXIT_FAILURE);
}

输出示例:

  $ ./sigbug
循环:23528(0)
循环:23528(0)
...
...省略循环的消息庞大的数字...
...
循环:23528(0)
循环:23528(0)
循环:23528(0)
循环:23528(0)
^ CLooping:23528(0)
循环:23528(0)
循环:23528(0)
循环:23528(0)
创建的管道:0(3,4)
分叉:23529(23528,45428)
暂停病人:23528
分叉:0(23529,23528)
暂停C:23529
^ ZUnpaused C:23529
取消暂停病人:23528
一个
b
打印C:5
循环:23529(1)
暂停C:23529
家长:5
循环:23528(1)
暂停病人:23528
^ ZUnpaused病人:23528
b
取消暂停C:23529
23529:关闭(FD [0] = 3)失败:9错误的文件描述符
23528:关闭(FD [1] = 4)失败:9错误的文件描述符
$

错误修正code

这里的code的修订版什么对我来说更合适的逻辑。它不包括 err_syserr(),因为函数调用没有失败。在 secondSel 不需要变量;信号处理程序就只包含一个存根返回; (可省略)。它不循环拼了命在一开始,因为我把一个暂停的地方等待中断。

 的#include<&signal.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;静态无效handleSignal(INT SIG)
{
    返回;
}INT主要(无效)
{
    INT FD [2];
    INT PIPE1 = 0;
    将为pid_t与fork1 = 0;    如果(信号(SIGINT,handleSignal)== SIG_ERR)
    {
        的printf(错误捕获信号C \\ n);
        出口(1);
    }    的printf(等待中断\\ n);
    暂停();
    信号(SIGINT,SIG_IGN);    PIPE1 =管(FD);
    如果(PIPE1℃,)
    {
        fprintf中(标准错误,错误创建管1 \\ n);
        出口(1);
    }
    fprintf中(标准错误,创建的管道:%D(%D,%D)\\ n,PIPE1,FD [0],FD [1]);    与fork1 = fork()的;
    如果(与fork1℃,)
    {
        fprintf中(标准错误,错误与叉子\\ n);
        出口(1);
    }    fprintf中(标准错误,叉形:%D(%D,%D)\\ n,与fork1(INT)GETPID(),(INT)getppid());
    信号(SIGTSTP,handleSignal);    如果(与fork1 == 0)
    {
        dup2(FD [1],1);
        关闭(FD [0]);
        关闭(FD [1]);
        而(1)
        {
            fprintf中(标准错误,暂停C:%d个\\ N(INT)GETPID());
            暂停();
            fprintf中(标准错误,取消暂停C:%d个\\ N(INT)GETPID());
            INT randNum1 =兰特()%9 + 1;
            fprintf中(标准错误,打印C:%d个\\ N,randNum1);
            如果(的printf(%d个\\ N,randNum1)2)
            {
                fprintf中(标准错误,打印C:失败\\ n);
                的clearerr(标准输出);
            }
            fflush(标准输出);
        }
    }
    其他
    {
        dup2(FD [0],0);
        关闭(FD [0]);
        关闭(FD [1]);
        而(1)
        {
            fprintf中(标准错误,暂停病人:%d个\\ N(INT)GETPID());
            暂停();
            fprintf中(标准错误,取消暂停病人:%d个\\ N(INT)GETPID());
            INT F = 99;
            如果(scanf的(%d个,&放大器;!F)= 1)
            {
                fprintf中(标准错误,scanf的病人:失败\\ n);
                的clearerr(标准输入);
            }
            其他
                的printf(父数:%d \\ n,F);
        }
    }    返回0;
}

输出示例:

  $ ./sigbug-jl1
等待中断
^ CCreated管:0(3,4)
分叉:23554(23553,45428)
暂停病人:23553
分叉:0(23554,23553)
暂停C:23554
^ ZUnpaused C:23554
打印C:5
取消暂停病人:23553
暂停C:23554
家长:5
暂停病人:23553
^ ZUnpaused C:23554
打印C:8
取消暂停病人:23553
暂停C:23554
家长:8
暂停病人:23553
^ ZUnpaused病人:23553
取消暂停C:23554
打印C:6
暂停C:23554
家长:6
暂停病人:23553
^ \\退出:3
$

我用SIGQUIT终止程序,因为中断被禁止。

I'm attempting to get my child process to generate a random number between 1 -9, then send it to my parent process for which it would display it to screen each time control + Z is pressed. I'm also using dup2() to change the stream from printf and scanf to the read and write ends of the pipe for each process.

The code works as below, you press control C to start the main program. Now it waits for control Z to be pressed for each time a random number is sent from child and displayed at parent. The issue I am facing is, it seems the child only runs once when control Z is pressed again, it only runs the parent code. The pipe also only ever shows the same number and never changes so its not being updated. I also noticed that if I remove the printf line before the dup function printf("a \n"), it prints out random numbers....however the problem with the child running once still exists.

Would appreciate if someone can assist me on this. Cheers.

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

int selection = 0;
int secondSel = 0;
int fd[2];
int pipe1;
pid_t fork1;

void handleSignal(int sig)
{
  if (sig == SIGINT)
    {
      selection = 1;
      secondSel = 1;
    }
  if (sig == SIGTSTP)
    {
      selection = 1;
    }
}

int main()
{
int firstPipe[2];
  int secondPipe[2];

//wait for control+C
  if (signal(SIGINT, handleSignal) == SIG_ERR)
    {
    printf("Error catching signal C \n");
    exit(0);
    }

  while(1)
    {
      //wait till control c is pressed
      if (selection == 1)
    {
      signal(SIGINT, SIG_IGN);

      if (secondSel == 1)
        {
          pipe1 = pipe(fd);
        }
      if (pipe1 < 0)
        {
          printf("Error creating pipe 1 \n");
          exit(1);
        }

      if (secondSel == 1)
        {
          fork1 = fork();
        }


      if (fork1 < 0)
        {
          printf("Error with first fork. \n");
          exit(1);
        }
      else if (fork1 == 0) //first child process
        {
          signal(SIGTSTP, handleSignal);
          pause();
          printf("a \n");
          int randNum1;
          close(fd[0]);
          dup2(fd[1], 1);
          randNum1 = rand() % 9 + 1;

          printf("%d ", randNum1);
          fflush(stdout);
          close(fd[1]);
        }
      else //parent
        {
          signal(SIGTSTP, handleSignal);
          pause();
          printf("b \n");
          int f;
          close(fd[1]);
          dup2(fd[0], 0);
          scanf("%d \n", &f);
          printf("%d \n", f);
          close(fd[0]);
        }
      secondSel = 0;
    }
    }

}

解决方案

The comment/code:

//wait for control+C
if (signal(SIGINT, handleSignal) == SIG_ERR)

is a disconcerting start. The signal() function sets the signal handler for SIGINT, but it no way waits for a signal to arrive. The simplest fix for that is to add a call to pause() after that block of code.

Inside the infinite loop, the code:

        if (secondSel == 1)
        {   
            pipe1 = pipe(fd);
        }   
        if (pipe1 < 0)
        {   
            printf("Error creating pipe 1 \n");
            exit(1);
        } 

is sub-optimal and/or confusing. Since pipe1 is only set when pipe() is called, there's no need to test it on each iteration. Error messages should be reported on standard error, and should not have trailing blanks. The code should be:

        if (secondSel == 1)
        {   
            if (pipe(fd) < 0)
            {
                fprintf(stderr, "Error creating pipe 1\n");
                exit(1);
            }
        }

There's a similar test on the same variable protecting the fork().

Your code carefully closes the pipe after the first cycle, but never reopens it. That is ultimately why the second and subsequent iterations fail. Your code would be better if you didn't try to do everything on each cycle. Also, using standard output for debugging information is subject to various problems; it is better to use standard error instead — especially when standard output isn't working properly.

Instrumented code

Here's an instrumented version of your code. The err_syserr() function is almost generic; the condition using usleep() is peculiar to this code and ensures that the output of the terminated error message is normally sequenced. I put the tests on the function calls that would be failing — the first close failed on the second cycle because the pipe descriptors are all closed at the end of the first cycle. (Note that reusing pipe() is no help after the fork() — the pipes in the parent and child would not be connected to each other.)

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void err_syserr(const char *fmt, ...);

int selection = 0;
int secondSel = 0;
int fd[2];
int pipe1 = 0;
pid_t fork1 = 0;

static void handleSignal(int sig)
{
    if (sig == SIGINT)
    {
        selection = 1;
        secondSel = 1;
    }
    if (sig == SIGTSTP)
    {
        selection = 1;
    }
}

int main(void)
{
    // wait for control+C
    if (signal(SIGINT, handleSignal) == SIG_ERR)
    {
        printf("Error catching signal C\n");
        exit(1);
    }
    //printf("Waiting for interrupt\n");
    //pause();

    while (1)
    {
        fprintf(stderr, "Looping: %d (%d)\n", (int)getpid(), selection);
        // wait till control c is pressed
        if (selection == 1)
        {
            signal(SIGINT, SIG_IGN);

            if (secondSel == 1)
            {
                pipe1 = pipe(fd);
                fprintf(stderr, "Created pipe: %d (%d, %d)\n", pipe1, fd[0], fd[1]);
            }
            if (pipe1 < 0)
            {
                printf("Error creating pipe 1\n");
                exit(1);
            }

            if (secondSel == 1)
            {
                fork1 = fork();
                fprintf(stderr, "Forked: %d (%d, %d)\n", fork1, (int)getpid(), (int)getppid());
            }

            if (fork1 < 0)
            {
                printf("Error with first fork.\n");
                exit(1);
            }
            else if (fork1 == 0) // first child process
            {
                signal(SIGTSTP, handleSignal);
                fprintf(stderr, "Pausing C: %d\n", (int)getpid());
                pause();
                fprintf(stderr, "Unpaused C: %d\n", (int)getpid());
                printf("a\n");
                if (close(fd[0]) != 0)
                    err_syserr("close(fd[0]=%d) failed", fd[0]);
                if (dup2(fd[1], 1) < 0)
                    err_syserr("dup2(fd[1]=%d, 1) failed", fd[1]);
                int randNum1 = rand() % 9 + 1;

                fprintf(stderr, "Print C: %d\n", randNum1);
                if (printf("%d\n", randNum1) < 2)
                {
                    fprintf(stderr, "Print C: failed\n");
                    clearerr(stdout);
                }
                fflush(stdout);
                if (close(fd[1]) != 0)
                    err_syserr("close(fd[1]=%d) failed", fd[1]);
            }
            else // parent
            {
                signal(SIGTSTP, handleSignal);
                fprintf(stderr, "Pausing P: %d\n", (int)getpid());
                pause();
                fprintf(stderr, "Unpaused P: %d\n", (int)getpid());
                printf("b\n");
                if (close(fd[1]) != 0)
                    err_syserr("close(fd[1]=%d) failed", fd[1]);
                if (dup2(fd[0], 0) < 0)
                    err_syserr("dup2(fd[0]=%d, 0) failed", fd[0]);
                int f = 99;
                if (scanf("%d", &f) != 1)
                {
                    fprintf(stderr, "Scanf P: failed\n");
                    clearerr(stdin);
                }
                printf("Parent: %d\n", f);
                if (close(fd[0]) < 0)
                    err_syserr("close(fd[0]=%d) failed", fd[0]);
            }
            secondSel = 0;
        }
    }
    return 0;
}

#include <errno.h>
#include <string.h>
#include <stdarg.h>

static void err_syserr(const char *fmt, ...)
{
    int errnum = errno;
    va_list args;
    if (fork1 != 0)     /* Parent waits 1/4 second */
        usleep(250000);
    fprintf(stderr, "%d: ", (int)getpid());
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    if (errnum != 0)
        fprintf(stderr, ": %d %s", errnum, strerror(errnum));
    fputc('\n', stderr);
    exit(EXIT_FAILURE);
}

Example output:

$ ./sigbug
Looping: 23528 (0)
Looping: 23528 (0)
…
…huge numbers of 'looping' messages omitted…
…
Looping: 23528 (0)
Looping: 23528 (0)
Looping: 23528 (0)
Looping: 23528 (0)
^CLooping: 23528 (0)
Looping: 23528 (0)
Looping: 23528 (0)
Looping: 23528 (0)
Created pipe: 0 (3, 4)
Forked: 23529 (23528, 45428)
Pausing P: 23528
Forked: 0 (23529, 23528)
Pausing C: 23529
^ZUnpaused C: 23529
Unpaused P: 23528
a
b
Print C: 5
Looping: 23529 (1)
Pausing C: 23529
Parent: 5
Looping: 23528 (1)
Pausing P: 23528
^ZUnpaused P: 23528
b
Unpaused C: 23529
23529: close(fd[0]=3) failed: 9 Bad file descriptor
23528: close(fd[1]=4) failed: 9 Bad file descriptor
$

Bug fixed code

Here's a revised version of the code with what seems to me more appropriate logic. It doesn't include err_syserr() because the function calls aren't failing. The selection and secondSel variables aren't needed; the signal handler becomes a stub that just contains return; (which could be omitted). It doesn't loop like mad at the start because I put a pause in place to wait for the interrupt.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void handleSignal(int sig)
{
    return;
}

int main(void)
{
    int fd[2];
    int pipe1 = 0;
    pid_t fork1 = 0;

    if (signal(SIGINT, handleSignal) == SIG_ERR)
    {
        printf("Error catching signal C\n");
        exit(1);
    }

    printf("Waiting for interrupt\n");
    pause();
    signal(SIGINT, SIG_IGN);

    pipe1 = pipe(fd);
    if (pipe1 < 0)
    {
        fprintf(stderr, "Error creating pipe 1\n");
        exit(1);
    }
    fprintf(stderr, "Created pipe: %d (%d, %d)\n", pipe1, fd[0], fd[1]);

    fork1 = fork();
    if (fork1 < 0)
    {
        fprintf(stderr, "Error with fork.\n");
        exit(1);
    }

    fprintf(stderr, "Forked: %d (%d, %d)\n", fork1, (int)getpid(), (int)getppid());
    signal(SIGTSTP, handleSignal);

    if (fork1 == 0)
    {
        dup2(fd[1], 1);
        close(fd[0]);
        close(fd[1]);
        while (1)
        {
            fprintf(stderr, "Pausing C: %d\n", (int)getpid());
            pause();
            fprintf(stderr, "Unpaused C: %d\n", (int)getpid());
            int randNum1 = rand() % 9 + 1;
            fprintf(stderr, "Print C: %d\n", randNum1);
            if (printf("%d\n", randNum1) < 2)
            {
                fprintf(stderr, "Print C: failed\n");
                clearerr(stdout);
            }
            fflush(stdout);
        }
    }
    else
    {
        dup2(fd[0], 0);
        close(fd[0]);
        close(fd[1]);
        while (1)
        {
            fprintf(stderr, "Pausing P: %d\n", (int)getpid());
            pause();
            fprintf(stderr, "Unpaused P: %d\n", (int)getpid());
            int f = 99;
            if (scanf("%d", &f) != 1)
            {
                fprintf(stderr, "Scanf P: failed\n");
                clearerr(stdin);
            }
            else
                printf("Parent: %d\n", f);
        }
    }

    return 0;
}

Example output:

$  ./sigbug-jl1
Waiting for interrupt
^CCreated pipe: 0 (3, 4)
Forked: 23554 (23553, 45428)
Pausing P: 23553
Forked: 0 (23554, 23553)
Pausing C: 23554
^ZUnpaused C: 23554
Print C: 5
Unpaused P: 23553
Pausing C: 23554
Parent: 5
Pausing P: 23553
^ZUnpaused C: 23554
Print C: 8
Unpaused P: 23553
Pausing C: 23554
Parent: 8
Pausing P: 23553
^ZUnpaused P: 23553
Unpaused C: 23554
Print C: 6
Pausing C: 23554
Parent: 6
Pausing P: 23553
^\Quit: 3
$

I used SIGQUIT to terminate the program since interrupts are disabled.

这篇关于C,得到一个父和子进程使用的信号工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆