2013-07-15 56 views
0
gcc (GCC) 4.1.2 
c89 

你好,鎖定和解鎖多線程應用程序

Decideing,我需要做的在多線程應用程序鎖定和解鎖。

保持代碼片段的簡短。我有一個全球渠道結構。即

typedef struct tag_channel channel_t; 
struct tag_channel {....}; 

我有3個函數使用API​​來設置和處理其消息隊列上的通道。

我的主線程#1將調用這個函數

apr_status_t set_ss7_channel_state(channel_t *channel) 
{ 
    /* API call to set channel - non-blocking ASYNC call that returns immediately 
     wait for event in evt_loop */ 
    setChanState(channel); 
} 

事件循環中產生的線程#2開始。其他功能可以觸發相同的頻道購買將頻道放在消息隊列中。

static void* APR_THREAD_FUNC evt_loop(apr_thread_t *thd, void *data) 
{ 
    while(is_looping) { 
     /* Get event and channel from message API message queue */  
     waitevt(); 
     if(channel_process(channel) != TRUE) { 
      /* clean up */  
     } 
    } 
} 

從線程#稱爲Process通道2

apr_status_t channel_process(channel) 
{ 
    /* process channel here based on the event 
    /* lock channel */ 
    /* do some processing */ 
    /* unlock channel */ 
} 

所以基本上調用工作這樣一個單信道:

1) setChanState(channel) thread #1 -> puts channel on an API message queue 
2) evt_loop(...) thread #2 will retrieve the event and the channel structure 
3) process_channel(channel) will process the channel on thread #2 

我在想,我需要阻止渠道結構,因爲這個渠道可能會有其他活動? 我已經在channel_process上放置了阻塞。

非常感謝您的任何建議,

+0

我不明白你打算如何在這裏使用多個線程。此外,您的問題不可能像現在這樣回答,因爲「此通道上的其他事件」不是簡單地發生,而是其他代碼執行某些會影響通道的代碼的結果。不知道更多,這是不可能回答。 –

回答

1

是的,你必須阻止通道結構。重點在於當#2線程正在處理最後一個事件(以及與之相關的數據)時,線程#1能夠覆蓋通道結構的內容。

有多種方式來同步這個。通過阻塞線程#1,直到線程#2完成,或者您可以簡單地添加關鍵部分到結構的排序。或者你建立你的渠道結構作爲一系列工作來處理。

-1

這將取決於通道結構的內容,它究竟是如何通過setChanState和waitev交付。

如果tag_channel不包含引用(例如指針,文件描述符,或其他任何間接別的東西)和setChanState/waitev提供複印件它線程2(通過例如管道),那麼你得到有效實施Actor模型,並接近實現通信順序進程(甚至更好),並且不需要進一步的鎖定。

否則,你必須有互斥體來保護通道結構本身或其間接引用的內容。

+0

我想說,不僅如果tag_channel確實包含必須保護結構的引用。即使它是一堆相關的整數值,如果生產者線程在消費者線程仍在運行時將開始更改值,則會遭受不一致。 – junix

+0

@junix,您的評論是以對tag_channel的內容或其用途的無知而編寫的。原始問題引用了消息隊列,並且完全有可能原始海報正在使用(可能是偶然)使用actor模型(或更好的CSP)。如果你不知道這些是什麼,我建議你看看它們,它們很有用。 – bazza

+0

是的,你是對的。我忽略了tag_channel的內容 - 或者更好:我沒有對它的內容做任何假設。由於沒有關於該主題的信息,我不認爲在此做出假設是安全的。 OP是否實施CSP或他是否想實施演員模型也不清楚。此外,還不清楚OP是否將通道信息傳遞給線程#2,而線程#1仍然保持對它的引用。鑑於這些不確定因素,我在你的文章中添加了一條評論,因爲我認爲你的答案不符合「所有情況」。 – junix