C++ c++;11进程间原子和互斥体

C++ c++;11进程间原子和互斥体,c++,c++11,C++,C++11,我有一个Linux程序,它生成几个进程(fork)并通过POSIX共享内存进行通信。我希望每个进程分配一个id(0-255)。我的意图是在共享内存区域中放置一个位向量(初始化为零),并原子地比较和交换一个位以分配一个id 有没有一种c++11友好的方法可以做到这一点?我可以创建一个原子位集吗?我可以跨进程使用互斥锁吗?如何确保构造函数在所有进程中调用一次且仅调用一次?C++11线程原语(互斥体、原子等)是线程原语。C++标准不引用进程,并且这些工具中的大多数不跨进程互操作。 本标准中仅提及非规范

我有一个Linux程序,它生成几个进程(fork)并通过POSIX共享内存进行通信。我希望每个进程分配一个id(0-255)。我的意图是在共享内存区域中放置一个位向量(初始化为零),并原子地比较和交换一个位以分配一个id


有没有一种c++11友好的方法可以做到这一点?我可以创建一个原子位集吗?我可以跨进程使用互斥锁吗?如何确保构造函数在所有进程中调用一次且仅调用一次?

C++11线程原语(互斥体、原子等)是线程原语。C++标准不引用进程,并且这些工具中的大多数不跨进程互操作。 本标准中仅提及非规范性符号中的过程,该符号表示:

无锁的操作也应该是无地址的。也就是说,通过两个不同的地址在同一内存位置上的原子操作将进行原子通信。实现不应依赖于每个进程的任何状态。此限制允许通过多次映射到进程的内存和两个进程之间共享的内存进行通信


在这种非规范性符号之外,线程原语并不打算成为实现进程间通信的手段。当这些对象放置在共享内存中时(除了上面提到的无锁原子),它们的行为是未定义的。

您可以在共享内存块中使用互斥体,但互斥体必须声明为共享的,因此在共享内存中使用互斥体并不罕见,您可以创建自己的类,非常简单:

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;
}

@aleguna,因为我想要一个介于0-255之间的值,当一个进程离开这个程序时,它应该释放它的ID以便重用。@Nicolas我回答了我的问题,并选择了最基本的必要信息来提出一个可以让我解决问题的问题。我不想让人们改变问题所在。我可以创建一个任意的同步问题,并询问它关于posix跨进程共享内存的问题,这个问题仍然存在。如果它能帮助你,假装我问了一个共享的数据结构以及C++互斥或原子如何工作。@ dsChasz:因此,你有一个@ NicolBolas,你显然错过了基于第一个问题的观点。我问的是c++11互斥体和原子如何跨进程工作(嘿,标题匹配!)。我举了一个具体的例子使之具体化。然后继续对示例进行挑剔。如果您没有答案,那很好,但是没有理由尝试移动目标柱来回答我的问题。C++11没有进程间函数。Boost::Interprocess可能为您提供了一些用于解决此问题的工具。[atomics.lockfree]包括“[注意:无锁操作也应该是无地址的。也就是说,通过两个不同地址在同一内存位置上的原子操作将进行原子通信。实现不应依赖于任何每个进程状态。此限制允许通过多次映射到进程的内存和内存进行通信这是两个进程之间共享的。-结束语]“亲爱的@Nicol Bolas,你的答案很好,但我找不到任何地方或任何关于这方面的书,所以我仍然对在共享内存中使用C++11互斥体感到困惑。(正如我所知,如果使用pthread_PROCESS_shared,pthread mutex是可以的)我真的希望在参考文献中包括这一点,比如这个答案是完全错误的。Jefrrey Yasskin已经指出了一个原因(std::atomic实际上非常适合共享内存IPC,有时是必要的)在他的评论中,但他的评论很容易掩饰。互斥体也可以用于共享内存IPC,尽管标准库互斥体确实不是用于这种用途的。而且,需要明确的是,该标准的意图显然是原子能应可用于IPC。Jeffrey在该标准中的引用表明了这一点至少,我不知道C++11中的标准是否已经包含了这一点。