2010-10-20 88 views
2

我有一個使用線程池實現的基於UDP的應用程序。線程池共享資源鎖定問題

的消息推到一個隊列,當有事情要做或隊列中的消息線程池被喚醒。線程池處理每個消息並將它們傳遞給保持某種狀態的會話對象。即UDP分組是會話的一部分,並且會話正在重新組裝大塊數據。

該會話對象需要訪問共享資源。但是,另一個會話對象也可以從資源中讀取,但不能在寫入時讀取。

現在的問題是,對話對象DoWork的方法可以從不同的線程調用,我需要防止任何人寫的。所以要做到這一點,我需要鎖定資源。

這是問題出現的地方。如果我使用標準的互斥鎖,它不能在線程間移植,所以我會嘗試訪問資源,並且應該能夠將數據放入資源中,但除非我是鎖定資源的原始線程,否則我不能這樣做。

它是想我需要一個會話密鑰來訪問的資源,而不是我的 線程ID。

我該如何解決這個問題?在這裏提升shared_mutex似乎有點受限。

回答

0

我正在做的是使資源成爲一個對象。 框架版本看起來 這樣的:

例如

class Resource 
{ 
public: 
    enum {READ, WRITE}; 

    void Open(int mode=READ) 
    { 
    if (mode == WRITE){ 
     Lock(); 
     // Access resource 
    } else if (mode == READ){ 
     // Try to get read access (scoped version) 
     boost::shared_lock<boost::shared_mutex> read(lock_, boost::try_to_lock); 
     if (!read){ 
      // throw exception 
     } 

     // Read access to resource 
    } 
    } 

    Lock() 
    { 
    lock_.lock_upgrade(); 
    lock_.unlock_upgrade_and_lock(); 
    } 

    Unlock() 
    { 
    lock_.unlock(); 
    } 

private: 
    boost::shared_mutex lock_; 
} 

現在我可以有多個閱讀器。當我想寫入資源(在任何時候),我可以調用Lock()。 Open也是。完成後可以調用解鎖。不同的線程可以解鎖,而不是鎖定它的線程。

另外,在寫入時會防止讀取,直到調用解鎖爲止。

0

聽起來像是你想有一個reader/writer lock

+0

好的,我知道我需要一個讀寫器鎖,但是我不知道的和剛剛通過實驗發現的是另一個線程可以解鎖資源。 – Matt 2010-10-20 02:49:30

0

據我瞭解oyu需要多個讀者和一個作家模型。如果是這樣,你可以在「getter」中創建boost :: shared_lock,在「setter」中創建boost :: unique_lock(這兩個都是針對「lock_」創建的)。

回覆你的方法「打開」:「讀」是一個本地對象,因此在完成「打開」將被刪除。什麼意思,當你離開「打開」時,lock_將被解鎖(shared_lock的析構函數這麼做)。