如何将内核模块中的自定义Linux信号广播到所有正在运行的进程

时间:2015-05-07 20:13:01

标签: c linux-kernel

我编写了一个内核模块,它向用户空间提供有关硬件中断的一些信息。目前,用户空间应用程序使用IOCTL将其PID x发送到内核模块。然后内核模块使用此PID查找任务并发送信号:

#define CUSTOM_SIGNAL 44
struct siginfo info;
memset(&info, 0, sizeof(struct siginfo));
info.si_signo = CUSTOM_SIGNAL;
info.si_code = SI_QUEUE;
info.si_int = 0;
struct task_struct *t = pid_task(find_pid_ns(x, &init_pid_ns), PIDTYPE_PID);
send_sig_info(CUSTOM_SIGNAL, &info, t); 

这非常有效。但是,我发现维护单个信号的PID接收器的动态列表相当棘手。出于这个原因,我想将信号默认广播到所有正在运行的进程(因此它们无需注册即可通知 - 它只是发生了。)

我能想到的一个模仿这种行为的例子是系统关闭信号。是否可以简单地广播我的CUSTOM_SIGNAL,或者我是否需要迭代所有PID,如上所述逐个发送。或者是否有代表广播的特殊任务?

1 个答案:

答案 0 :(得分:2)

这是完全错误的。

  

我编写了一个内核模块,提供了一些关于a的信息   硬件中断到用户空间。目前,用户空间   应用程序使用IOCTL将其PID x发送到内核模块。该   然后内核模块使用此PID来查找任务并发送信号

首先,您可以通过当前访问调用线程任务结构。获得这样的PID,然后找到它就没有任何意义。

此外,您的代码示例建议您不要锁定RCU,如果您启用了调试,这将是您将学习的错误。

  

这非常有效。但是,我觉得维持一个相当棘手   单个信号的PID接收器的动态列表。出于这个原因我   想将广播信号默认为所有正在运行的进程   (所以他们不需要注册才能得到通知 - 它恰好发生了。)

这原则同样是错误的。你会引起虚假的唤醒,这有可能带来很多奇怪的屁股乐趣(不是所有东西都像人们想象的那样'原子')。

而是创建一个可以获取文件描述符的设备驱动程序。感兴趣的主题将轮询描述符,这就是他们将如何了解该事件。