阻塞线程中断

Blocking thread interrupt

本文关键字:中断 线程      更新时间:2023-10-16

下面的进程函数从队列中读取数据并处理它。masterQueuewait_and_pop函数进行阻塞调用。因此,在队列中存在可以读取的数据之前,控制不会向前移动。

class Context
{
  void launch()
  {
   boost::thread thread1(boost::bind(&Context::push,this ) );
   boost::thread thread2(boost::bind(&Context::process,this ) );
   std::cout<<"Joining Thread1"<<std::endl;
   thread1.join();
   std::cout<<"Joining Thread2"<<std::endl;
   thread2.join();
  }
  void process()
  {
    Data data;
    while(status)
    {
      _masterQueue.wait_and_pop(data); //Blocking Call
      //Do something with data
    }
  }
  void push()
  {
    while(status)
    {
       //Depending on some internal logic, data is generated
      _masterQueue.push(data);
    }
  }
};

status是一个布尔值(在全局范围内)。这个布尔值默认设置为true。只有当信号被捕获时,如SIGINT, SIGSESV等,它才会被更改为false。在这种情况下,while循环被退出,程序可以安全退出。

bool status = true;
void signalHandler(int signum)
{
  std::cout<<"SigNum"<<signum;
  status = false;
  exit(signum);
}
int main()
{
  signal(SIGABRT, signalHandler);
  signal(SIGINT, signalHandler);
  signal(SIGSEGV, signalHandler);
  Context context;
  context.launch();
}
因为当一个信号被抛出时,没有新的数据被thread2推送,所以thread1中的控制被卡在
_masterQueue.wait_and_pop(data);

如何强制中断阻塞调用?

  1. 是否可以在不改变wait_and_pop的内部工作的情况下实现这一点
  2. 设置超时不是一个选项,因为数据可能在几个小时内到达队列一次或每秒多次
  3. 我是否在接收信号时推送特定类型的数据,例如INT_MAX/INT_MIN,进程函数被编码为识别并退出循环。

超时实际上是你的答案在得到答案或中断时打破循环

您还可以通过让中断向队列

推送一个noop来进行一些欺骗。

你可以在需要完成.interrupt()线程时尝试。

如果.wait_and_pop()使用标准的boost机制来等待(条件变量或类似的),那么即使在阻塞状态下,也肯定会通过抛出boost::thread_interrupted异常而中断。如果您的masterQueue类是可靠的异常处理,那么这样的中断是安全的。