2015-06-04 128 views
1

以下进程函数从队列中读取数据并对其进行处理。 的wait_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(); 
} 

,因为没有新的数据是由线程2推当信号被抛出,线程1控制是停留在

_masterQueue.wait_and_pop(data); 

如何强制此阻塞调用被打断?

  1. 是否有可能实现这一点没有改变wait_and_pop
  2. 配售超时的内部工作是不是一种选择,因为数据可以在队列曾经在几个小时或多次第二
  3. 到达
  4. 我是否在接收信号时推送特定类型的数据,例如INT_MAX/INT_MIN,其中过程函数编码为识别并退出循环。
+0

退出时线程是否结束?为什么解除封锁? – perencia

回答

0

超时实际上是你的答案 你打破你的环路上得到答案或具有中断

你也可以恶搞的东西有点具有inturrupt推向一个空操作到队列

+0

我了解推向队列解决方案。我的要求不允许我放置超时。但是,我很想知道如何以及在何处放置超时代码 –

+0

如果您在3秒后超时,并且输入时间为1秒,则与没有超时相同。如果输入在5秒后到来,则您暂停一次并等待2秒钟。唯一的影响是,如果输入正确的时候你正在迭代,但那是可以忽略的。将您的超时设置为等待发生中性破坏的最大容差。其余的你应该能够弄清楚。 –

+0

这个类是通用的。它在多种情况下用于顺序读取和处理数据。超时值因此将特定于每种情况。然而,我怎么看,我不能帮忙,但硬编码这个值 –

0

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

如果.wait_and_pop()用来等待(条件变量或类似)标准增压机构,它肯定会甚至阻塞状态,通过投掷抛出boost :: thread_interrupted异常中断。如果你的类对于异常是可靠的,那么这样的中断是安全的。

+0

它使用条件变量。你的意思是类似thread1.interrupt() –

+0

如何访问signalHandler中的thread1和thread2?我是否让他们成为Context的数据成员? –

+0

是的,你应该让线程可用于signalHandler,并从它调用'thread1.interrupt()'和'thread2.interrupt()'。 – Tsyvarev