Linux環境下線程消息同步的陷阱

咱們程序中經常會使用到線程間的消息同步處理,好比如下一段僞碼html

var message = "";
void func() 
{
  1. 啓動線程Thread(該線程中填充message的內容);

  2. 阻塞,直到等待到完成message填充的事件;

  3. 處理message;

  ....
}
void Thread() 
{
  1. 經過某種處理填充message;

  2. 觸發func中的阻塞事件;
}

咱們一般會使用條件變量來完成相似狀況的線程同步處理
linux

  • 好比windows平臺下CreateEvent,WaitForSingleObject,SetEvent...;編程

  • Linux平臺下的pthread_cond_init,pthread_cond_wait,pthread_cond_signal...。windows


      看上去很完美的模型。可是在Linux平臺下使用條件變量來完成這種需求是有風險的,要知道操做系統對線程的調度是咱們不可控的。設想這樣一種狀況:func中步驟1的線程有可能已經觸發了阻塞事件,可是func步驟2還未執行。這時這個事件若是在Linux平臺下使用條件變量就會丟失通知。這樣對於步驟2就面臨着永遠阻塞或者超時這些咱們不指望的邏輯。(這種狀況在我寫的客戶端網絡SDK的linux版本下遇過的,我發出去一條帶有標識的消息,而後利用條件變量阻塞10秒等待這個標識消息,可是時常會碰見等待超時的狀況,按說是不可能超時的,最後通過詳細調查才發現是因爲pthread庫的條件變量觸發機制致使的。)可是在windows下使用Event卻不會出現這種狀況。網絡

舉個簡單的例子:多線程

  • linux下pthread庫的條件變量觸發機制比如:你和女神妹子約好在某個地方見面,理應你先到的,結果由於你堵車妹子先到了,一看你沒來,生氣走了。約會泡湯,哭去吧你。ide

  • windows下的事件的觸發機制比如:你和屌絲妹子約好在某個地方見面,理應你先到,但你故意晚來想氣走妹子,結果妹子先到卻一直等你。約會進行中,哭去吧你。post

那麼咱們有沒有辦法在linux平臺下實現一種更可靠的消息同步機制,屌絲福音:使用posix信號量sem_init,sem_t imedwait,sem_post...。另外使用select和epoll的水平觸發也能夠變向實現這種狀況下的消息同步(監控管道一端的讀,一端寫來觸發消息)。spa

推薦閱讀:《Linux 的多線程編程的高效開發經驗》操作系統

相關文章
相關標籤/搜索