我有一个Linux程序,它产生多个进程(fork)并通过POSIX共享内存进行通信。我想让每个进程分配一个id(0-255)。我的目的是将一个位向量放在共享内存区域(初始化为零)并进行原子比较并交换一点来分配一个id。
是否有一种c ++ 11友好的方式来做到这一点?我可以创建一个原子位集吗?我可以跨进程使用互斥吗?我如何确保在所有进程中只调用一次构造函数?
答案 0 :(得分:15)
C ++ 11线程基元(互斥,原子等)是线程基元。他们对流程一无所知,也不是实现流程间沟通的手段。
由于C ++ 11标准没有提及进程或进程间通信,这些原语放在进程共享内存中时的行为(内存映射文件,某种进程外全局映射)内存等)未定义。
答案 1 :(得分:6)
你可以在共享内存块中使用互斥锁,但必须将互斥锁声明为SHARED,因此在共享内存中使用互斥锁并不常见,你可以自己创建类,这很简单:
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;
}