【问题标题】:Killing a child process from a signal handler从信号处理程序中杀死子进程
【发布时间】:2012-11-01 08:34:08
【问题描述】:

我正在编写一个简单的 shell,我必须使用 execv 将一个子进程分叉为一个外部程序。我必须将信号 TSTP(Cntl+Z) 发送到信号处理程序,然后终止当前正在运行的子进程。我的问题是我找不到将子 pid 传递给信号处理程序的方法。如果我在处理程序中执行 getpid(),它只会返回父 pid。我还尝试在子进程中将子 pid 设置为 getpid() ,并将该变量作为全局变量,但这也不起作用。这是我到目前为止的一些代码。

void handler(int);
//in main
if (!built_in_cmd(myArgc,myArgs)) {
    pid_t pid;
    char *x = myArgs[0];
    if((pid=fork())<0)
        printf("Parent: fork() process failed");
    else {
        if (pid == 0) {
            y=getpid();
            printf("Parent: My child has been spawned. %d %d\n",y,getppid());
            execv(x, myArgs);
            exit(0);
        }
        else {
            signal(SIGTSTP,handler);
            wait(0);
            printf("Parent: My child has terminated.\n");
        }
    }
}
return;

//outside main
void handler(int signo){
    kill(idk,SIGKILL);
} 

【问题讨论】:

  • fork() 返回子 PID。将它放在一个全局变量中并在信号处理程序中使用它。
  • 顺便说一句,您的“父母:我的孩子已经出生”这行是孩子打印的,而不是它声称的父母。

标签: c linux shell unix


【解决方案1】:

信号本质上是异步的,除了通过全局变量之外,没有办法向它们传递任何额外的状态。假设您只有一个线程在等待孩子,那么使用全局是安全的,但除此之外没有多线程安全的方法:

// At global scope
pid_t child_pid = (pid_t)-1;
...
void myfunc()
{
    pid_t pid;
    if((pid = fork()) < 0)
        ...
    else if(pid == 0)
        ...
    else
    {
        child_pid = pid;
        ...
    }
}

【讨论】:

  • 不能将额外的状态传递给信号处理程序,这并不完全正确。当然,使用全局变量是最简单的事情,但是您可以将 pid(和任何任意数据)写入管道并在信号处理程序中读取它。
猜你喜欢
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
  • 2011-03-28
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 2010-12-08
  • 1970-01-01
相关资源
最近更新 更多