编写设备驱动程序

线程无法接收信号

线程收到信号时,可以唤醒 sema_p_sig()cv_wait_sig()cv_timedwait_sig() 函数。由于某些线程无法接收信号,因此可能会出现问题。例如,如果由于应用程序调用 close(2) 而导致调用 close(9E),则可以收到信号。但是,如果是从 exit(2) 处理(关闭所有打开的文件描述符)中调用 close(9E),则线程无法收到信号。如果线程无法收到信号,则 sema_p_sig() 的行为与 sema_p() 相同,cv_wait_sig() 的行为与 cv_wait() 相同,cv_timedwait_sig() 的行为与 cv_timedwait() 相同。

对于可能永远不会发生的事件,请注意避免永久休眠。永远不会发生的事件会创建不可中止 (defunct) 的线程并使设备不可用,除非重新引导系统。失效进程无法接收信号。

要检测当前线程是否可接收信号,请使用 ddi_can_receive_sig(9F) 函数。如果 ddi_can_receive_sig() 函数返回 B_TRUE,则以上函数可在收到信号时唤醒。如果 ddi_can_receive_sig() 函数返回 B_FALSE,则以上函数无法在收到信号时唤醒。如果 ddi_can_receive_sig() 函数返回 B_FALSE,则驱动程序会使用替代方法(如 timeout(9F) 函数)重新唤醒。

出现此问题的一个重要情况是使用串行端口。如果远程系统声明了流量控制,并且 close(9E) 函数在尝试清空输出数据时阻塞,则端口会堵塞,直到解决流量控制情况或重新引导系统为止。此类驱动程序应检测到此情况并设置计时器,以便在流量控制情况持续过长时间时中止清空操作。

此问题还会影响 qwait_sig(9F) 函数。此函数将在《STREAMS Programming Guide》中的第 7  章 “STREAMS Framework – Kernel Level”中介绍。