首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >正确使用进程间共享的pthread互斥锁

正确使用进程间共享的pthread互斥锁
EN

Stack Overflow用户
提问于 2017-03-06 23:05:53
回答 2查看 10.6K关注 0票数 10

在stackoverflow上有很多关于pthread互斥锁是否可以在进程间共享的问题,但我没有找到关于共享互斥锁初始化的问题/答案。

据我所知,使用进程共享互斥锁的常见方法如下:分配一个共享内存块,在共享内存块上初始化一个pthread互斥锁,使用它。

在创建共享内存的情况下,如果多个进程尝试分配具有相同密钥ID的共享内存块,则由操作系统处理。好的,但我不明白的是,如何安全地初始化共享内存块上的互斥?

pthread_mutex_init没有提供任何安全的方法来从不同的进程同时初始化pthread_mutex_t,这对吗?如果是,我如何为进程提供独占访问以初始化共享的“互斥”?我如何确定另一个进程是否成功地初始化了互斥?

第二个问题与阻塞互斥锁的进程崩溃的情况有关。好的,有一个健壮的互斥锁可以处理这种情况并返回相应的错误代码。那么共享内存块呢?似乎一个进程应该注意它是否是使用共享内存销毁它的最后一个进程。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-07 09:56:10

pthread_mutex_init没有提供任何安全的方法来从不同的进程同时初始化pthread_mutex_t,这对吗?

对,是这样。您需要确保只有一个进程在互斥锁上调用pthread_mutex_init(),并且在该调用成功返回之前,没有任何进程尝试对互斥锁进行操作。

例如,对于POSIX shm_open()共享内存区域,您可以让进程尝试使用O_CREATO_EXCL标志打开该区域,以便只有一个进程能够成功创建该区域。然后,此进程负责调整共享内存区域的大小,并使用pthread_mutex_init()初始化互斥锁。然后,在打开共享内存区域之前,其他进程必须等待初始化进程的某种通知-例如,您可以让这些进程阻止打开一个先进先出O_RDONLY,并让初始化进程通过打开O_WRONLY通知它们(这将导致打开成功)。

通常,共享内存段不是进程之间的唯一通信通道。通常,您将通过UNIX域套接字引导通信,并在其上协商共享内存区域的设置,甚至可能通过套接字使用SCM_RIGHTS消息传递共享内存区域文件描述符。然后,共享内存区域将用于加速对性能敏感的IPC。

票数 8
EN

Stack Overflow用户

发布于 2018-12-02 11:18:29

我使用mmap创建一个共享内存块。

代码语言:javascript
复制
int fd = open(filename, O_RDWR | O_CLOEXEC);

当文件不存在时,执行fd < 0,然后尝试初始化互斥内存。

代码语言:javascript
复制
fd = open(filename, O_RDWR | O_CREAT | O_CLOEXEC | O_TRUNC | O_EXCL,
            S_IRUSR);
if(fd < 0) {
     // two processes might try to create the file simultaneously.
     // one open is success, the other one fail because of O_EXCL.
     sleep_random_10ms();
     continue; // continue and try again.
}

注意:由于S_IRUSR的原因,在open成功创建文件后,文件仍然不可写。任何其他进程都将无法使用O_RDWR打开该文件,因此第一个open仍然会失败。当我们初始化互斥锁时,没有进程会使用互斥锁。

创建文件后,我们照常初始化互斥锁

代码语言:javascript
复制
pthread_mutexattr_init(&att);
pthread_mutexattr_setrobust(&att);
pthread_mutexattr_setpshared(&att, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&mutex, &att)
write(fd, &mutex, sizeof(mutex))
fchmod(fd, S_IRUSR | S_IWUSR)
fclose(fd);

最后两个步骤使文件可写,以便任何其他进程在第一次尝试时都能成功打开文件。

我们开始像往常一样使用互斥锁

代码语言:javascript
复制
mutex = (pthread_mutex_t*) mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0);
pthread_mutex_lock(mutex);
....
pthread_mutex_unlock(mutex);

清理

代码语言:javascript
复制
munmap(&mutex);
close(fd);
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42628949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档