栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

记录一次linux信号量sem

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

记录一次linux信号量sem

linux提供了互斥量pthread_mutex_t(pthread库) 用于线程间同步,进程间同步提供了信号量sem_t。如果把pthread_mutex_t放到共享内存中,并将其属性设置为PTHREAD_PROCESS_SHARED,则也能实现进程间的同步,相对而言比较麻烦。一般直接使用信号量更加方便。

这里讨论使用具名信号量以便在无血缘关系的进程之间做同步,主要涉及下面5个函数:

sem_open();//打开或者创建信号量
sem_wait();//获取信号量
sem_post();//挂出信号量
sem_close();//关闭信号量
sem_unlink();//销毁信号量

其中sem_unlink()的行为比较让人迷惑,linux内核文档描述为:

DEscriptION
       sem_unlink() removes the named semaphore referred to by name.  The semaphore name is removed immediately.  The
       semaphore is destroyed once all other processes that have the semaphore open close it.

意思是执行该函数,会立即移除信号量的id名,但是只有所有打开了该信号量的进程执行了sem_close(),才会真正销毁这个信号量。问题就出现了,id名与信号量实体可能出现分离,因为当某个进程A执行了sem_unlink,并不能确保其他进程关闭了信号量(也就是执行了sem_close),结果是信号量实体依然在内核中存在,且其他进程依然工作正常。有时候这种结果正是我们想要的,但有时候则不一定。更严重的问题是,当进程A再次打开这个信号量时(使用sem_open(),id名不变),已经无法通过id名找到之前那个信号量实体了,打开的是一个全新的信号量,虽然id名与之前一样,内容却没有关联了。

        这样一来,进程A就无法与其他进程同步了。只有其他进程也执行一次sem_close和sem_unlink,并重新打开这个id名(sem_open()),才能重新连接,继续同步。因此“removes the named semaphore referred to by name”,应该理解为"立即解除name 与信号量实体的绑定关系",这样比较符合实测结果。

        在使用共享内存的过程中,shmctl(id,IPC_RMID,NULL)移除共享内存,好像也有类似的问题,没有实测过。

通常当一个进程退出时,需要执行sem_unlink,也有可能程序异常退出没有执行这一步,问题比较复杂。最好是当某个进程重启了,其他相关进程也重启一下,确保所有进程打开的是同一个信号量实体,可以一定程度避免信号量和共享内存连接异常的问题。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/642419.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号