我编写了一个内核模块,它向用户空间提供有关硬件中断的一些信息。目前,用户空间应用程序使用 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,按上述方式一一发送。或者是否有代表广播的特殊任务?
最佳答案
这是完全错误的。
I have written a kernel module that supplies some information about a hardware interrupt to user-space. Currently, the user-space application uses IOCTL to send its PID x to the kernel module. The kernel module then uses this PID to find the task and send the signal
首先,您可以通过current来调用线程任务结构。像这样获取PID然后再找它是没有任何意义的。
此外,您的代码示例建议您不要锁定 RCU,如果启用了调试,您会发现这是一个错误。
This works really well. However, I find it rather tricky to maintain a dynamic list of PID receivers for a single signal. For this reason I would like to broadcast the signal be default to all running processes (so they need not register to be notified -- it just happens).
这在原理上同样是错误的。你会引起虚假的唤醒,这可能会带来很多奇怪的乐趣(并不是所有的事情都像人们想象的那样“原子”)。
而是创建一个可以获取文件描述符的设备驱动程序。感兴趣的线程将轮询描述符,这就是他们了解事件的方式。
关于c - 如何将自定义 Linux 信号从内核模块广播到所有正在运行的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30110809/