我一直在为真正奇怪的问题而烦恼。内核模块无法在没有 printk 的情况下向用户应用程序发送信号(或用户应用程序无法接收),必须在发送信号之后或之前执行虚拟 printk。
实际上,即使 printk 为空,它也能很好地工作。但是,我正试图了解发生了什么。
有什么想法吗?
这是发生了什么:
A - 内核) 字符设备类型模块获取中断。
它提取数据并向用户发送信号。
/* 必须在这里执行 printk */
返回 IRQ 句柄。
B-用户)
接收信号。
发出系统调用并从字符设备的缓冲区中读取数据。 (复制到用户)
内核:
void irq_handler(){
int i;
for(i =0; i < 32; i++)
GPIOdata[i] = read_gpio_status(i);
struct task_struct *p = find_task_by_pid(processinfo.pid);
if (NULL == p)
return;
send_sig(SIGUSR1, p, 0);
/* have to add printk here */
return IRQ_HANDLED
}
用户:
void signal_handler(int sig) {
char data[32];
ioctl(fd, READ_Data_from_Char_device, &data);
}
最佳答案
如果您使用 signal
而不是 sigaction
来设置处理程序,请记住,signal
会在收到信号后删除处理程序。并且你应该屏蔽信号,这样它就不会在信号处理程序中运行时中断你的进程。我也不确定处理程序内部的系统调用 ioctl
(查看异步信号安全函数部分下的 man7 signal)。
调用 printk
可能会减慢这些调用周围其他操作的执行速度(因为它们在 I/O 或缓冲上被阻塞),因此它们会使同步变慢(因此同步中的任何错误都可能不会发生)。
关于c - 来自内核的信号用户应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17690432/