【问题标题】:System V msgrcv blocking in threadSystem V msgrcv 在线程中阻塞
【发布时间】:2017-07-21 14:29:53
【问题描述】:

我有一个应用程序,它具有信号处理程序并创建了一个线程来处理消息队列。 下面是信号处理程序,

   /*! \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 标志。)"

为什么线程/msgrcv 没有收到信号? 如果我将线程作为主循环,那么它会返回并成功退出应用程序。

【问题讨论】:

  • 如何发送SIGINT 信号?您是否更改了任何信号掩码?
  • 不,我没有更改信号掩码
  • SIGINT 信号呢?你如何生成它?
  • 执行命令kill -2

标签: c multithreading pthreads signals message-queue


【解决方案1】:

如果一个信号被发送到一个进程,一个没有阻塞它的线程会处理它,但它是哪个线程并没有明确说明。你说你没有在所有其他线程上阻塞SIGINT。所以你看到的行为最可能的解释是信号是由主线程处理的,而不是调用msgrcv的线程。

要解决此问题,您可以在所有线程上阻止 SIGINT,但调用 msgrcv 的线程除外。这将确保信号由该线程处理。

如果您有多个线程需要中断,这将不起作用。在这种情况下,您可能需要为所有线程阻塞SIGINT,并在特殊的中断处理线程中使用sigwait 来接收SIGINT 信号。然后该线程可以向所有需要中断的线程发送另一个信号(可能是SIGUSR1),每个这样的线程都有一个pthread_kill。或者您也可以使用pthread_cancel,具体取决于您的需求。

【讨论】:

  • 那么我也可以在加入线程之前调用pthread_kill。实际上我有大约 11-12 个线程的多线程应用程序。
  • 当然,如果这对你有用,但我认为处理线程提前退出的情况并不容易。
  • 弗洛里安,在我的应用程序中,其他线程正在使用 SIGALRM。并且这个 msgrcv 给出了 EINTR 错误。有什么解决办法吗?我可以将线程设置为仅使用 pthread_sigmask 接收特定信号吗?
  • 是的,您可以用pthread_sigmask 阻止SIGALRM。但该线程将无法再使用sleep,您必须改用nanosleepusleep 函数。
  • 什么例子?也许是时候发布一个新问题了。
猜你喜欢
  • 2019-12-06
  • 1970-01-01
  • 2021-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
相关资源
最近更新 更多