我有一个应用程序,它有信号处理程序并创建了一个处理消息队列的线程。 下面是信号处理程序,
/*! \Register handle on SIGINT. */
signal(SIGINT, CloseHandler);
VOID CloseHandler(INT32 sig)
{
if(sig == SIGINT)
gAppExitFlag = 1;
return;
}
我创建了一个可连接的线程来接收消息队列,
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if(0 != (count = pthread_create(&ModemDetectionHandel, &attr, &ModemDetectionOperation, (void *)&gAppContext)))
{
DS3_ERROR(DS3_TELEMETRY_APP, "Error in creating thread ModemDetectionOperation");
}
在线程中,我创建了一个消息队列,并使用msgflg 0调用msgrcv。 所以它会阻止,直到收到任何消息。 现在当我发送SIGINT进行处理但是msgrcv没有回来并在msgrcv中阻塞线程。
我的应用程序陷入加入线程。
根据msgrcv手册页" *呼叫过程发出信号。在这种情况下,系统调用失败,并将errno设置为EINTR。 (msgrcv()在被中断后永远不会自动重启 一个信号处理程序,无论在建立信号处理程序时SA_RESTART标志的设置如何。)"
为什么thread / msgrcv没有收到信号? 如果我将线程作为主循环,那么它会返回并且应用程序成功退出。
答案 0 :(得分:1)
如果信号被发送到进程,则一个未阻止它的线程将处理它,但未指定它将是哪个线程。你说你没有在所有其他线程上阻止static CDUVariable Baud() { return { baud, "0"}; }
。因此,您看到的行为最可能的解释是信号由主线程处理,而不是调用SIGINT
的线程。
要解决此问题,您可以在除调用msgrcv
的线程之外的所有线程上阻止SIGINT
。这将确保信号由该线程处理。
如果您有多个需要中断的线程,这将无效。在这种情况下,您可能需要阻塞所有线程的msgrcv
,并在特殊的中断处理线程中使用SIGINT
来接收sigwait
信号。然后,该线程可以向需要中断的所有线程发送另一个信号(可能是SIGINT
),每个线程都有一个SIGUSR1
。或者也许您也可以使用pthread_kill
,具体取决于您的需求。