关于sem_unlink什么时候删除信号量
sem_unlink在man手册里有这么一段话:
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.
这段话的意思是说,sem_unlink会马上删除指定的信号量名,但要等到所有打开该信号量的进程关闭该信号量后才删除该信号。详细地说,当进程创建一个有名信号量,会在/dev/shm下生成一个sem.xxx的文件,所有打开该信号量的进程(包括创建它的进程)都会增加该文件的引用计数,并且这个计数由内核管理。当调用sem_unlink时,/dev/shm下的sem.xxx文件会马上被删除,但是信号量本身并没有被删除,所有已打开该信号量的进程仍能正常使用它。直到所有打开该信号量的进程关闭该信号量后,内核才真正删除信号量。
因此,信号量跟sem.xxx并不是共存亡的。下面来测试下:
/* sem_create.cpp */
#include <iostream>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <unistd.h>
#include <cerrno>
#include <cstring> int main()
{
sem_t *psem = sem_open( "/sem_test",O_CREAT,S_IRWXU, );
if ( SEM_FAILED == psem )
{
std::cout << "sem_open fail:" << strerror(errno) << std::endl;
return ;
} int sval = ;
sem_getvalue( psem,&sval ); std::cout << "sleep now ....value is " << sval << std::endl;
sleep( ); sem_getvalue( psem,&sval );
std::cout << "wake up ....value is " << sval << std::endl; sem_post( psem );
sem_getvalue( psem,&sval );
std::cout << "raise value and try again ....value is " << sval << std::endl; sem_close( psem );
}
/**
*
* sem_destruct.cpp
*/ #include <iostream>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <cerrno>
#include <cstring> int main()
{
sem_t *psem = sem_open( "/sem_test",O_CREAT,S_IRWXU, );
if ( SEM_FAILED == psem )
{
std::cout << "sem_open fail:" << strerror(errno) << std::endl;
return ;
} std::cout << "decrease value and remove sem now..." << std::endl;
sem_wait ( psem ); sem_close( psem );
sem_unlink( "/sem_test" ); std::cout << "sem should remove from /dev/shm,but not really remove" << std::endl;
}
分别编译上面的文件:
g++ -pthread -o sem_create sem_create.cpp
g++ -pthread -o sem_destruct sem_destruct.cpp
先运行sem_create,再运行sem_destruct这时个可以看到输出为:
xzc@xzc-HP-ProBook-4446s:~/code/sem$ ./sem_create
sleep now ....value is
xzc@xzc-HP-ProBook-4446s:~/code/sem$ ./sem_destruct
decrease value and remove sem now...
sem should remove from /dev/shm,but not really remove
wake up ....value is
raise value and try again ....value is
可以看到,即使sem_destruct从/dev/shm把信号量删除了,ls /dev/shm也确认对应的文件删除了。但是经过sleep的sem_create进程在wake up后仍能对信号量进行操作。
可以看到,有名信号量一旦打开后,跟名字并没有多大关系。下面再来测试有名信号量调用sem_unlink但仍有进程在使用,这时另外一个进程又要创建同名信号量的情况
/**
*
* sem_again.cpp
*/ #include <iostream>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <unistd.h>
#include <cerrno>
#include <cstring> int main()
{
sem_t *psem = sem_open( "/sem_test",O_CREAT|O_EXCL,S_IRWXU, );
if ( SEM_FAILED == psem )
{
std::cout << "sem_open fail:" << strerror(errno) << std::endl;
return ;
} int sval = ;
sem_getvalue( psem,&sval ); //std::cout << "sleep now ....value is " << sval << std::endl;
//sleep( 30 ); sem_getvalue( psem,&sval );
std::cout << "value is " << sval << std::endl; sem_post( psem );
sem_getvalue( psem,&sval );
std::cout << "raise value and try again ....value is " << sval << std::endl; sem_close( psem );
sem_unlink( "/sem_test" );
}
编译一下:g++ -pthread -o sem_again sem_again.cpp,然后依次运行sem_create、sem_destruct、sem_again
xzc@xzc-HP-ProBook-4446s:~/code/sem$ ./sem_create
sleep now ....value is xzc@xzc-HP-ProBook-4446s:~/code/sem$ ./sem_destruct
decrease value and remove sem now...
sem should remove from /dev/shm,but not really remove xzc@xzc-HP-ProBook-4446s:~/code/sem$ ./sem_again
value is
raise value and try again ....value is wake up ....value is
raise value and try again ....value is
在sem_again中特意使用了O_CREATE|O_EXCL标志,如果已存在同名信号量,则创建失败。但从上面的结果来看,创建成功并且互不干扰。也就是说,一个有名信号量,在打开并调用sem_unlink后可以当作无名信号量来使用(但这时新的进程还想使用该信号量,不可能了)。
注:上面只做了简单测试,并未测试sem_unlink后各进程的竞争情况,在生产环境请自行测试。
PS:在debian 6上,不用unistd.h也能调用sleep函数,在ubuntu 14.04上不行。在debian 6上是链接的库是-lrt,在ubuntu 14.04上是-pthread,-lrt不行。linux这是要闹哪样。
关于sem_unlink什么时候删除信号量的更多相关文章
- Linux 共享内存 详解
一.什么是共享内存区 共享内存区是最快的可用IPC形式.它允许多个不相关的进程去访问同一部分逻辑内存.如果需要在两个运行中的进程之间传输数据,共享内存将是一种效率极高的解决方案.一旦这样的内存区映射到 ...
- 【转载】Linux的进程间通信-信号量
原文:Linux的进程间通信-信号量 Linux的进程间通信-信号量 版权声明: 本文章内容在非商业使用前提下可无需授权任意转载.发布. 转载.发布请务必注明作者和其微博.微信公众号地址,以便读者询问 ...
- 进程间通信之POSIX信号量
POSIX信号量接口,意在解决XSI信号量接口的几个不足之处: POSIX信号量接口相比于XSI信号量接口,允许更高性能的实现. POSIX信号量接口简单易用:没有信号量集,其中一些接口模仿了我们熟悉 ...
- Linux进程同步之POSIX信号量
POSIX信号量是属于POSIX标准系统接口定义的实时扩展部分.在SUS(Single UNIX Specification)单一规范中,定义的XSI IPC中也同样定义了人们通常称为System V ...
- Linux多线程实践(5) --Posix信号量与互斥量解决生产者消费者问题
Posix信号量 Posix 信号量 有名信号量 无名信号量 sem_open sem_init sem_close sem_destroy sem_unlink sem_wait sem_post ...
- POSIX信号量
DESCRIPTION POSIX 信号量允许进程间和线程间同步他们的操作. 一个信号量是一个整型(integer),其值不能小于0. 信号量允许2中操作:给信号量的值加1(sem_post); 给信 ...
- linux c编程:Posix信号量
POSIX信号量接口,意在解决XSI信号量接口的几个不足之处: POSIX信号量接口相比于XSI信号量接口,允许更高性能的实现. POSIX信号量接口简单易用:没有信号量集,其中一些接口模仿了我们熟悉 ...
- 进程同步与相互排斥:POSIX有名信号量
在 POSIX 标准中,信号量分两种,一种是无名信号量,一种是有名信号量. 无名信号量一般用于线程间同步或相互排斥,而有名信号量一般用于进程间同步或相互排斥. 它们的差别和管道及命名管道的差别类似.无 ...
- C实现进程间通信(管道; 共享内存,信号量)
最近学习了操作系统的并发:以下是关于进程间实现并发,通信的两个方法. 例子: 求100000个浮点数的和.要求: (1)随机生成100000个浮点数(父进程). (2)然后创建4个后代进程,分别求25 ...
随机推荐
- html li标签前面添加图标三种方法
今天无聊写下这个例子,希望对初学者有帮助,代码如下 <!DOCTYPE html> <html> <head> <meta charset="utf ...
- JS~对img标签进行优化,使用onerror进行默认图像显示
对于网站图像的不显示有很多原因,网络问题,文件本身问题,文件URL问题等,而当图像加载失败时会触发onerror这个事件,我们利用这点,可以有效的避免图像加载失败的尴尬! JS代码 //图像加载出错时 ...
- Swift 2.0初探:值得注意的新特性
转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度的WWDC大会如期而至,在大会上A ...
- HDU 5274(树链剖分)
树链剖分第一题QAQ,纪念下 #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream ...
- git的0基础使用
1.申请一个git帐号 2.项目开发者将你增加这个项目 3.在终端随意一个目录克隆 该项目地址 git clone 该项目地址 4.进nginx配置 5.更新的时候进入项目目录 git pull
- MySQL复制协议
http://hamilton.duapp.com/detail?articleId=27
- CodeSmith使用总结--读取一个表试试
我感觉CodeSmith对于我的最大用途是不用我手动创建每个表的Model.BLL和DAL了,那些繁琐的工作真的让我很无语. CodeSmith要读取数据库中的表就要先连接数据库. 新建一个数据库连接 ...
- Android的启动模式
启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的<Activity>标签的android:launchMode属性设置: 启动模式有4种,分别 ...
- 点击推送消息跳转处理(iOS)
当用户点击收到的推送消息时候,我希望打开APP,并且跳转到对应的界面,这就需要在AppDelegate里面对代理方法进行处理. 当用户点击推送消息打开APP的时候会调用 - (BOOL)applica ...
- sqlserver2005重新安装(安装汇编错误,安装程序无法连接到数据库服务进行服务配置)
2014-01-09 16:41 1687人阅读 评论(1) 收藏 举报 分类: 数据库(1) 版权声明:本文为博主原创文章,未经博主允许不得转载. sqlserver2005重新安装(安装汇编错误, ...