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

时间:2016-11-07 21:05:18

标签: c linux process sqlite fork

我最近学会了如何处理整个CREATE TABLE company_analysis.extable ( name string, link_params struct<cid:STRING>, template string, day string, list_name string, id string) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' STORED AS TEXTFILE LOCATION '/analysis/company/extable'; 事情并最终编写了一些看起来像这样的代码:

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"); } } shell,但是有一个问题。如果您从sqlite3 shell中Ctrl + C,那么它也会终止父进程,并且行sqlite3永远不会运行。

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

我尝试通过尝试调用printf("Hi\n")来解决此问题:

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()失败。

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这样的简单内容(虽然这可能与原始问题无关)。

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

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

1 个答案:

答案 0 :(得分:-1)

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

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