【问题标题】:Ctrl-C issue in C -Signal handlingC - 信号处理中的 Ctrl-C 问题
【发布时间】:2013-12-01 12:06:24
【问题描述】:

我有一个关于信号处理的问题。

假设我有两个程序同时运行。我称它们为程序 1 和程序 2。

我在不同的终端窗口运行它们,因为一个程序等待另一个程序启动。它们旨在继续运行,直到我在两个窗口中都按 ctrl-c。我觉得这个方法有点麻烦。所以我想做的是在其中一个程序中添加一些东西。

意思是,我可以使用 ctrl-c 来停止 program1,并且 program2 一旦知道 program1 不再活动,就会停止。我在网上查了一下,看看是否有这样的例子,或者我不知道的 C 语言中的某些部分,我遇到了信号处理。

我知道信号处理涉及使程序根据给定的信号或信号的结构进行各种执行。这是正确的使用方法还是有其他方法?

我在网上看到,如果信号是 ctrl-C,使用信号处理会在终端中弄乱 ctrl-C 命令?

如果有一些示例代码,我们也会非常感谢有关信号处理的解释。

根据给出的答案,我根据给出的内容编写了一个示例代码:

#include <signal.h>
......
......
sigset_t SIGUSR1;
sigset_t SIGUSR2;
int signal;

void trap(int signal);
......
......
void trap(int signal)
{
int signal;
signal == SIGUSR1
}

对不起,如果我写这篇文章看起来很愚蠢,但我仍然想知道它是如何工作的。

【问题讨论】:

  • 如果一个程序接收到 SIGTERM,则使用kill 系统调用从该程序向另一个程序发送相同的信号。我假设您可以访问这两个程序的 pid。
  • 对于 Linux/Unix:我认为最好的解决方案是如果 program1 forkexecl program2。那么当program2结束时,program1会得到SIGCHLD信号。在 Windows CreateProcess 和 WaitFor...

标签: c


【解决方案1】:

您可以使用标头signal.h 处理信号 CTRL+C 使用 SIGINT 处理

它可能像这样工作:

   void func(int sig)
    {
    switch(sig)
    {
    case SINGINT:
    //Do whatever you want
    break;
    default :
    break;
    }
    }

    int main()
    {
    //Handle SIGINT
    signal(SIGINT,func);

    return 0;
    }

【讨论】:

  • 感谢您的代码。 +1 OP 应该使用 SIGUSR1 或 SIGUSR2
【解决方案2】:

“或者还有其他方法吗?” - 这是一个 UNIX 倾斜的答案。

这个主题非常广泛 - 它被称为 IPC - 进程间通信。协作进程可以通过多种方法相互“对话”,信号只是其中一种,以下是一些方法:

signals
shared memory objects
sockets
message queues
files

信号是名称 SIG[something],并在内核内部以数字表示。 kill -l 将为您列出可用信号及其名称。 SIGUSR1 和 SIGUSR2 旨在让用户应用程序相互通信。考虑使用它们。不用担心 SIGUSR1 代表的数字,只需在代码中使用名称即可。

使用信号:在接收时捕获信号并设置全局变量。在发送端调用kill() 函数。

SIGINT (CTRL/C) 被终端用来停止或中断正在运行的进程。所以考虑改用 SIGUSR1 和 SIGUSR2。通过像这样抢占 SIGINT,您会发现您可能会创建需要使用 CTRL/C 的情况。但它被你的代码困住了,所以它没有效果。 SIGUSRn 没有这个问题。因此您不必担心争夺单个信号的使用(多种含义)。

Linux 详细信息: 试试这个来自 tldp.org 的链接:http://www.advancedlinuxprogramming.com/alp-folder/alp-ch05-ipc.pdf

编辑:

prog1,等待的那个:

volatile int go=0;
void s_handler(int sig)
{
   go=1;
}


int main()
{
  signal(SIGUSR1, s_handler);
  while(go==0)
    usleep(500);
  //  run the rest of the code here when I wake up
  return 0;
}

prog2,唤醒 prog1 的那个 - 你需要 prog1 的 pid。 将 pid 作为命令行参数传递 prog2 [pid goes here]

int main(int argc, char **argv)
{
  if(argc>1)
  {
     pid_t pid=(pid_t)atoi(argv[1]);
     if(kill(pid, 0)==0 &&  kill(pid, SIGUSR1)!=0)// check pid, then signal
     {
        perror("Can't send signal to other process");
        exit(1);
     }
  }
  // run the rest of the code here
  return 0;
}

没有一种最正确的处理 IPC 的方法。选一个。以上使用信号。

没有错误检查只是基本逻辑。另一种方法是让 prog1 将 pid 写入文件,prog2 然后读取文件,读取并使用该 pid,然后删除文件。而不是命令行参数。

你决定。

【讨论】:

  • 好的,所以我应该使用 SIGUSR2 和 SIGUSR1 作为我可以应用的东西。通过捕获信号,这意味着我必须为陷阱创建一个函数,并且它必须在 program1 中?
  • 是的。捕获信号意味着例如:创建一个函数 F(),将其声明为信号处理程序,使用 signal == SIGUSR1: signal(SIGUSR1, F);并且必须声明函数 F:void F(int [variablename])。陷阱必须进入需要获取“你好,该走了”消息的过程。 kill() 调用进入“该醒来”的进程
  • 你能写一个示例代码,每个部分都有解释吗?我试图输入我的陷阱函数以了解它是如何工作的。我对如何调用 SIGUSR1 并在陷阱函数中使用 if 条件感到困惑。这对我来说是新的,所以请耐心等待。
猜你喜欢
  • 2016-01-08
  • 1970-01-01
  • 2015-02-11
  • 2011-09-23
  • 2011-01-29
  • 2021-09-07
  • 1970-01-01
相关资源
最近更新 更多