与struct指针共享内存互斥

我正在寻找一些关于我是否正确执行以下操作的反馈。 我正在努力移植一些Windows实时代码,这些代码大量使用了命名的互斥锁。 它需要一些搜索,但我遇到一些东西,说你可以使用共享内存作为linux中的互斥,使用shm open。

我不能在这里包含所有代码,但我将需要一些反馈的关键区域放在一起。 我的问题是如果我正确设置共享内存区域和互斥锁,以及我的指针是否设置正确,以及如何利用它来锁定/解锁。

volatile struct GenQ { volatile pthread_mutex_t *qMutexId volatile sem_t qSemId volatile int nexton volatile int nextoff } typedef struct Node{ void *qid char shmname[80] sem_t *semid pthread_mutex_t *mutexID struct node *next struct node *prev } void * init (const char *qname) { struct GenQ *myq; char mtxstr[80]; pthread_mutex_t *mutexQueAccess; int mode = S_IRWXU | S_IRWXG; int fd = 0; int status = 0; mtxstr[0] = "\0"; strcpy(mtxstr,"/"); strcat(mtxstr, qname); strcat(mtxstr, "_MTX"); fd = shm_open(mtxstr, O_CREATE | O_RDWR | O_TRUNC, mode); if (fd == -1) //err handling stuff status = ftruncate(fd, sizeof(pthread_mutex_t)); if(status==0){ //err handling stuff mutexQueAccess = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if(mutexQueAccess == MAP_FAILED) //err handling stuff pthread_mutexattr_t mutexAttr; pthread_mutexattr_init(&mutexAttr); pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(mutexQueAccess, &mutexAttr); myq->qMutexId = mutexQueAccess; newNode = (Node*)malloc(sizeof(node)); newNode->mutedID = mutexQueAccess; //add node to link list } void * openQ(*const char *qname) { pthread_mutex_t *mutexQueAccess; int fd = 0; int status = 0; char mtxstr[80]; int mode = S_IRWXU | S_IRWXG; mtxstr[0] = "\0"; strcpy(mtxstr,"/"); strcat(mtxstr, qname); strcat(mtxstr, "_MTX"); fd = shm_open(mtxstr, O_CREATE | O_RDWR, mode); //check fd for err mutexQueAccess = (pthread_mutex_t *)mmap(NULL, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); //check for err on mmap newNode = (Node*)malloc(sizeof(node)); newNode->mutedID = mutexQueAccess; //add node to link list } void * enque(const char *qname, char *msg_data) { node = //search for node pthread_mutex_lock(&(node->mutexQueAccess)) } 

我在一些代码中做了同样的事情,它看起来非常相似 – 部分原因。 这个想法非常简单。 分配给互斥锁的空间大小正好是sizeof(pthread_mutex_t) 。 您可以创建共享文件,对其进行mmap并在一个进程中初始化互斥锁,然后其他人可以简单地对该文件进行mmap并将其pthread_mutex_t *指针设置为该文件。

我不明白的一件事是struct GenQ部分。 volatile关键字暗示此结构驻留在共享内存中。 但是,如果它位于共享内存中,则存储在那里的互斥锁指针在创建它的进程外部将无效 。 互斥锁本身可能驻留在共享内存中,而其他进程也可能有指向互斥锁的指针,但共享内存区域在其虚拟地址空间内的确切位置可能不同,因此它们的指针值也会不同(因此指针应该对进程是私有的)。

因此,如果GenQ结构已经在共享内存中,为什么不简单地在GenQ结构中声明pthread_mutex_t不是实际互斥锁的指针空间),然后从主进程执行与上面相同的初始化码。 然后,您不需要为互斥锁使用单独的共享内存文件; 它将包含在与其他队列信息相同的共享内存空间中。

另外,请考虑将PTHREAD_MUTEX_ROBUST属性(使用pthread_mutexattr_setrobust )添加到互斥锁,以便在其中一个进程在保持锁定时崩溃的情况下可以恢复。

该代码看起来像这样:

  int err = pthread_mutex_lock(mutex_ptr); if (err) { if (err == EOWNERDEAD) { WARN("Mutex owner died while holding -- recovering"); err = pthread_mutex_consistent(mutex_ptr); if (err) FATAL("Huh?"); } else { FATAL("Wha?"); } } 

最后,我会对你使用volatile狡辩。 这既不必要也不充分。 如果在保留互斥锁时访问共享变量,则不需要volatile限定符。 如果你没有持有互斥锁,那么volatile本身就不足以确保正确的同步 – 你仍然需要使用某种primefaces增量/减量或primefaces比较和交换。