繁体   English   中英

如何防止子进程中的SIGINT传播到父进程并杀死父进程?

[英]How to prevent SIGINT in child process from propagating to and killing parent process?

我最近学会了如何做整个fork/exec/wait事情,最后写了一些看起来像这样剥离的代码:

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

int main() {
  pid_t x = fork();
  if (x == 0) {
    execlp("sqlite3", "sqlite3");
    printf("exec failed\n");
  } else {
    wait(NULL);
    printf("Hi\n");
  }
}

这很好,实际上最终打开sqlite3 shell,但有一个问题。 如果您从sqlite3 shell中Ctrl + C ,那么它也会终止父进程并且行printf("Hi\\n")永远不会运行。

我假设这是因为SIGINT正在传播到父进程,并且在进一步研究之后,我读到SIGINT将终止同一组中的所有进程,这意味着因为父和子共享同一组,所以他们都是终止。

我尝试通过尝试调用setpgid来解决这个问题:

int main() {
  pid_t x = fork();
  if (x == 0) {
    setpgid(getpid(), getpid()); // <-- Added in this line
    execlp("sqlite3", "sqlite3");
    printf("exec failed\n");
  } else {
    wait(NULL);
    printf("Hi\n");
  }
}

哪个运行正常,但这打破了sqlite3提示。 此外,在这种情况下, Ctrl + C仍然会杀死父级。 我决定尝试将它缩小甚至更多,然后发现一些奇怪的东西,并且难倒了。 只是将一个getpid()调用放入fork将使execlp()失败。

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

int main() {
  pid_t x = fork();
  if (x == 0) {
    getpid(); // <--- just adding this in makes it fail
    execlp("sqlite3", "sqlite3");
    printf("exec failed\n");
  } else {
    wait(NULL);
    printf("Hi\n");
  }
}

甚至不仅仅是对于sqlite3 ,而是对于像execlp("ls", "ls")这样的简单东西execlp("ls", "ls")尽管这可能与原始问题无关)。

我有点过头了,我想知道是否有人能指出我正确的方向。 我不太清楚从这里做什么。

  • 我在OSX 10.11上,正在使用clang进行编译。
  • clang --version :Apple LLVM 8.0.0版(clang-800.0.42.1)

你可以捕获SIGINT或写一个信号处理程序。 使用以下代码:

signal(SIGINT, sig_handler);
void sig_handler(int signo)
{
  if (signo == SIGINT)
    printf("received SIGINT\n");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM