2015-06-04 187 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