2

所以这是我现在遇到的问题,我创建了 2 个不同的程序(1 个将管理另一个,而另一个将被执行多次)。这些程序将通过信号来回通信。我的问题是,是否有可能(以及如何)获取发送信号的程序的进程 ID。我的程序使用 signal() 来捕获信号并使用 kill() 来发送它们。

4

4 回答 4

3

尽管 signal() 在标准 C 库中,但此函数不可移植,其行为取决于系统。最好使用 sigaction() ,它是 POSIX.1。

以下是如何将 sigaction 与处理程序 void h(int sig) 一起使用的示例:

int mysignal (int sig, void (*h)(int), int options)
{
    int r;
    struct sigaction s;
    s.sa_handler = h;
    sigemptyset (&s.sa_mask);
    s.sa_flags = options;
    r = sigaction (sig, &s, NULL);
    if (r < 0) perror (__func__);
    return r;
}

选项在 man sigaction 中描述。一个不错的选择是options=SA_RESTART

要知道发送信号的进程的 PID,请设置options=SA_SIGINFO并使用sa_sigaction回调而不是sa_handler; 它将收到一个siginfo_t结构,有一个si_pid字段。您可以使用 将数据与信号相关联sigqueue

一般来说,使用信号以安全的方式进行通信是一个坏主意(当发送n个信号时,只有第一个有机会被传递;没有钩子来关联其他数据;可用的用户信号只有两个) . 最好使用管道、命名管道或套接字。

于 2013-02-28T14:45:06.027 回答
2

不要使用signal(),它已经过时了。如果你有它,请改用它sigaction(),它提供了一个接口来获取发送者的进程 ID。

于 2013-02-28T08:23:33.517 回答
2

要获取发送信号的进程的进程 ID,您需要将其包含在选项 SA_SIGINFO 中。如果你这样做,sigaction 的接口会略有不同。以下是要使用的正确处理程序以及如何设置它的示例。(我将 SA_RESTART 作为一个选项包括在内只是因为它通常是一个好主意,但没有必要)

// example of a handler which checks the signalling pid
void handler(int sig, siginfo_t* info, void* vp) { 
  if (info->si_pid != getpid()) {
    // not from me (or my call to alarm)
    return;
  }
  // from me.  let me know alarm when off
  alarmWentOff = 1;
} 

这是我设置处理程序的一般代码:

typedef void InfoHandler(int, siginfo_t *, void *);

InfoHandler*
SignalWithInfo(int signum, InfoHandler* handler)
{
  struct sigaction action, old_action;

  memset(&action, 0, sizeof(struct sigaction));
  action.sa_sigaction = handler;  
  sigemptyset(&action.sa_mask); /* block sigs of type being handled */
  action.sa_flags = SA_RESTART|SA_SIGINFO; /* restart syscalls if possible */

  if (sigaction(signum, &action, &old_action) < 0)
perror("Signal error");
  return (old_action.sa_sigaction);
}

最后,对于这种特殊情况:

SignalWithInfo(SIGALRM, handler);  
于 2014-05-06T15:50:58.260 回答
-1

现在变了。信号信息显示的不是 1 个 pid,而是简单的数字。这符合killall过程。可能,有可能枚举 /proc/ 目录,当你找到 /proc/DIGIT 时,打开 /proc/DIGIT/comm,读取并关闭它。可能,acueried 名称将是“关闭”或“重新启动”

于 2017-04-20T10:18:07.683 回答