c - 来自内核的信号用户应用程序

标签 c linux-kernel signals

我一直在为真正奇怪的问题而烦恼。内核模块无法在没有 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/

相关文章:

node.js - 如何从另一个 Node.js 程序向 Heroku 上的 PostgREST 发送 SIGHUP 信号?

将序列化结构从 8 位系统复制到 32 位系统

c - 类型 "void"的值不能分配给类型为“void(*)(struct *Queue, int) 的实体”

linux - 英特尔处理器如何访问 Branch Trace Store 缓冲区?

c - 从线程向我的主信号发出信号?

c - 休眠一个进程并唤醒它

C - 递增和递减指针,然后检索值

c - C、Xcode 中的链接器错误。链接目标文件 (.o) 失败。不知道如何在 Xcode 中包含 makefile

linux - USB_MASS_STORAGE 和 USB_FILE_STORAGE 之间有什么区别以及如何最好地使用它?

c -/proc/sys/kernel/sched_child_runs_first 工作吗?