我有一个Linux程序,它会生成多个进程(fork),并通过POSIX共享内存进行通信。我希望每个进程都分配一个id(0-255)。我的想法是在共享内存区域中放置一个位向量(初始化为零),并原子地比较和交换一个位来分配id。
是否有c++11友好的方法来实现这一点?我可以创建一个原子位集吗?我可以跨进程使用互斥锁吗?如何确保构造函数在所有进程中只调用一次?
我有一个Linux程序,它会生成多个进程(fork),并通过POSIX共享内存进行通信。我希望每个进程都分配一个id(0-255)。我的想法是在共享内存区域中放置一个位向量(初始化为零),并原子地比较和交换一个位来分配id。
是否有c++11友好的方法来实现这一点?我可以创建一个原子位集吗?我可以跨进程使用互斥锁吗?如何确保构造函数在所有进程中只调用一次?
除了这个非规范的注释之外,线程原语并不意味着要实现进程间通信的手段。在共享内存中放置这些对象的行为(除了如上所述的无锁原子之外)是未定义的。无锁操作也应当是无地址操作的。也就是说,对于同一内存位置进行的两个不同地址的原子操作将以原子方式通信。实现不应依赖任何进程状态。此限制使得可以通过被映射到一个进程中多次或者被共享在两个进程之间的内存来进行通信。
您可以在共享内存块内使用互斥锁,但互斥锁必须声明为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;
}
virtual
析构函数吗?另外,最好使用pthread_mutex_t *handle
而不是每次使用时进行强制转换。 - Peter Cordes