2012-10-31 54 views
14

我有一個Linux程序,其派生幾個進程(叉),並通過POSIX共享存儲器通信。我想讓每個進程分配一個id(0-255)。我的意圖是在共享內存區域中放置一個位向量(初始化爲零),並通過原子比較和交換位分配一個ID。C++ 11間原子學和互斥

是否有一個C++ 11友好的方式來做到這一點?我可以創建一個原子位集嗎?我可以跨進程使用互斥鎖嗎?我如何確保構造函數在所有進程中只被調用一次?

+0

fork將子進程的PID返回給父進程,爲什麼不直接使用它來生成另一個呢?還是我誤解你的問題 – 2012-10-31 15:22:22

+0

@aleguna因爲我想從0-255的值,當退出該程序應該釋放它的ID可以重複使用。 – dschatz

+0

@dschatz:「*因爲我想一個值,範圍從0-255 *」這並不能解釋爲什麼* *您需要的。特別是當PID機制非常好*時。 –

回答

11

C++ 11線程原語(互斥體,原子等)是線程原語。他們對流程一無所知,而且他們不是實現流程間通信的手段。

由於C++ 11標準沒有提及進程或進程間通信,因此將這些基元置於進程共享內存(內存映射文件,某種全局進程外映射內存等)未定義。

+8

[atomics.lockfree] includes [注意:無鎖操作也應該是無地址的。也就是說,通過兩個不同地址在同一個內存位置上的原子操作將以原子方式進行通信,實現不應該依賴任何-process狀態,這個限制可以通過內存進行通信,這個內存被映射到一個進程中不止一次,並且通過兩個進程之間共享的內存進行通信。 - end note]「 –

+0

Dear @Nicol Bolas,你的答案很好,但是我找不到任何地方或者任何有關這方面的書籍,所以我仍然對在共享內存中使用C++ 11互斥體感到困惑。(據我所知,如果使用PTHREAD_PROCESS_SHARED,pthread mutex是可以的) –

4

您可以使用互斥共享的內存塊之內,但互斥量必須聲明爲SHARED,因此是不尋常的使用共享內存的內部互斥,U可以使自己的類,它是非常簡單的:

class Mutex { 
private: 
    void *_handle; 
public: 
    Mutex(void *shmMemMutex, bool recursive =false,); 
    virtual ~Mutex(); 

    void lock(); 
    void unlock(); 
    bool tryLock(); 
}; 

Mutex::Mutex(void *shmMemMutex, bool recursive) 
{ 
    _handle = shmMemMutex; 
    pthread_mutexattr_t attr; 
    ::pthread_mutexattr_init(&attr); 
    ::pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); 
    ::pthread_mutexattr_settype(&attr, recursive ? PTHREAD_MUTEX_RECURSIVE_NP : PTHREAD_MUTEX_FAST_NP); 

    if (::pthread_mutex_init((pthread_mutex_t*)_handle, &attr) == -1) { 
     ::free(_handle); 
     throw ThreadException("Unable to create mutex"); 
    } 
} 
Mutex::~Mutex() 
{ 
    ::pthread_mutex_destroy((pthread_mutex_t*)_handle); 
} 
void Mutex::lock() 
{ 
    if (::pthread_mutex_lock((pthread_mutex_t*)_handle) != 0) { 
     throw ThreadException("Unable to lock mutex"); 
    } 
} 
void Mutex::unlock() 
{ 
    if (::pthread_mutex_unlock((pthread_mutex_t*)_handle) != 0) { 
     throw ThreadException("Unable to unlock mutex"); 
    } 
} 
bool Mutex::tryLock() 
{ 
    int tryResult = ::pthread_mutex_trylock((pthread_mutex_t*)_handle); 
    if (tryResult != 0) { 
     if (EBUSY == tryResult) return false; 
     throw ThreadException("Unable to lock mutex"); 
    } 
    return true; 
}