posix和posix system v 比较信号量哪个更快

新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
白手起家, 积分 33, 距离下一级还需 167 积分
论坛徽章:0
本帖最后由 转瞬繁华 于
17:14 编辑
未命名.jpg (38.27 KB, 下载次数: 4)
17:10 上传
获得信号量后没有释放,第二次运行该程序时,无法取得信号量
未命名1.jpg (28.89 KB, 下载次数: 3)
17:10 上传
接着,我调用sem_unlink删除该信号量,第一成功,第二次失败
两次运行中的怎么访问的是同一个信号量?
这个有名信号量是存在本地或者是内存中?
怎么查询?
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
白手起家, 积分 8, 距离下一级还需 192 积分
论坛徽章:0
你创建信号量之后会在 /dev/shm 底下看到一个虚拟的文件
第一个问题
你程序关闭后,并没有删除这个文件,即没有unlink,信号量资源没释放,
所以你下一个程序获取不到
第二个问题
你删除一遍后,那个虚拟文件已经被删了 第二次删除当然就没了
小富即安, 积分 4602, 距离下一级还需 398 积分
论坛徽章:0
这个信号量就是为了应用于进程间的同步
北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:
广播电视节目制作经营许可证(京) 字第1234号
中国互联网协会会员&&联系我们:
感谢所有关心和支持过ChinaUnix的朋友们
转载本站内容请注明原作者名及出处linux用的是posix还是system v_百度知道system v信号量和POSIX信号量有哪些区别?_百度知道linux 内核信号量和 posix信号量内核实现上的区别_百度知道system V信号量和Posix信号量
system V信号量和Posix信号量
一、函数上的区别
& & & & 信号量有两种实现:传统的System V信号量和新的POSIX信号量。它们所提供的函数很容易被区分:对于所有System V信号量函数,在它们的名字里面没有下划线。例如,应该是semget()而不是sem_get()。然而,所有的的POSIX信号量函数都有一个下划线。下面列出了它们提供的所有函数清单:
sem_getvalue()
sem_post()
sem_timedwait()
sem_trywait()
sem_wait()
sem_destroy()
sem_init()
sem_close()
sem_open()
sem_unlink()
二、使用上的区别
1、XSI system V的信号量是信号量集,可以包括多个信号灯(有个数组),每个操作可以同时操作多个信号灯
& & &posix是单个信号灯,POSIX有名信号灯支持进程间通信,无名信号灯放在共享内存中时可以用于进程间通信。
2、POSIX信号量在有些平台并没有被实现,比如:SUSE8,而SYSTEM V大多数LINUX/UNIX都已经实现。两者都可以用于进程和线程间通信。但一般来说,system v信号量用于 进程间同步、有名信号灯既可用于线程间的同步,又可以用于进程间的同步、posix无名用于同一个进程的不同线程间,如果无名信号量要用于进程间同步,信号量要放在共享内存中。
3、POSIX有两种类型的信号量,有名信号量和无名信号量。有名信号量像system v信号量一样由一个名字标识。
4、POSIX通过sem_open单一的调用就完成了信号量的创建、初始化和权限的设置,而system v要两步。也就是说posix 信号是多线程,多进程安全的,而system v不是,可能会出现问题。
5、system V信号量通过一个int类型的值来标识自己(类似于调用open()返回的fd),而sem_open函数返回sem_t类型(长整形)作为posix信号量的标识值。
6、对于System V信号量你可以控制每次自增或是自减的信号量计数,而在Posix里面,信号量计数每次只能自增或是自减1。
7、Posix无名信号量提供一种非常驻的信号量机制。
8、相关进程: 如果进程是从一已经存在的进程创建,并最终操作这个创建进程的资源,那么这些进程被称为相关的。
三、注意事项
1、Posix有名信号灯的值是随内核持续的。也就是说,一个进程创建了一个信号灯,这个进程结束后,这个信号灯还存在,并且信号灯的值也不会改变。当持有某个信号灯锁的进程没有释放它就终止时,内核并不给该信号灯解锁
2、posix有名信号灯是通过内核持续的,一个进程创建一个信号灯,另外的进程可以通过该信号灯的外部名(创建信号灯使用的文件名)来访问它。posix基于内存的无名信号灯的持续性却是不定的,如果基于内存的信号灯是由单个进程内的各个线程共享的,那么该信号灯就是随进程持续的,当该进程终止时它也会消失。如果某个基于内存的信号灯是在不同进程间同步的,该信号灯必须存放在共享内存区中,这要只要该共享内存区存在,该信号灯就存在。
1、System V的信号量一般用于进程同步, 且是内核持续的, api为:semget、semctl、semop
2、Posix的有名信号量一般用于进程同步, 有名信号量是内核持续的. 有名信号量的api为:sem_open、sem_close、sem_unlink
3、Posix的无名信号量一般用于线程同步, 无名信号量是进程持续的, 无名信号量的api为:sem_init、sem_destroy
五、代码示例
* MultiProcessLock.cpp
Created on:
Detail: System V 信号量的使用
#include &sys/sem.h&
#include &stdio.h&
#include &stdlib.h&
#include &sys/types.h&
#include &sys/ipc.h&
#include &unistd.h&
#include &errno.h&
// val当执行SETVAL命令时使用。buf在IPC_STAT/IPC_SET命令中使用。代表了内核中使用的信号量的数据结构。array在使用GETALL/SETALL命令时使用的指针。
union semun
/*value for SETVAL*/
struct semid_ds *
/*buffer for IPC_STAT & IPC_SET*/
unsigned short int * /*array for GETALL & SETALL*/
struct seminfo *__
/*buffer for IPC_INFO*/
/* 等待一个二元信号量:阻塞直到信号量的值为正,然后将其减1
int binary_semaphore_wait(int semid)
struct sembuf sem_b;
sem_b.sem_num = 0;
/* 减一。 */
sem_b.sem_op = -1;
/* 允许撤销操作 */
sem_b.sem_flg = SEM_UNDO;
return semop (semid, &sem_b, 1);
/* 对一个二元信号量执行投递操作:将其值加一。 这个操作会立即返回 */
int binary_semaphore_post (int semid)
struct sembuf sem_b;
/* 使用(且仅使用)第一个信号量 */
sem_b.sem_num = 0;
/* 加一 */
sem_b.sem_op = 1;
/* 允许撤销操作 */
sem_b.sem_flg = SEM_UNDO;
return semop (semid, &sem_b, 1);
int main()
int iSemId;
* 通过 IPC_CREAT | IPC_EXCL 可以判断这个key对应的信号量是不是已经存在了,这可以用在单进程运行多次的情况下,只初始化一次信号量的情况下
int semflg = 0666 | IPC_CREAT | IPC_EXCL; // 如果key对应的((semflg &IPC_CREAT) &&(semflg &IPC_EXCL))非0, 那么semget返回EEXIST
key_t key = (key_t)0x;
/*创建一个新的信号量集*/
iSemId = semget(key, nsems, semflg);
if (iSemId & 0 && errno != EEXIST)
perror( &semget &) ;
return -1;
if(iSemId &= 0) // 这个信号量是第一次创建,则初始化
printf(&create: semid is %d\n&, iSemId);
/* 初始化信号量 */
semun sem_
sem_union.val = 1;
if(semctl(iSemId, 0, SETVAL, sem_union) == -1)
perror(&semctl&);
return -1;
// 这个信号量已经有了,则获得这个信号量值
iSemId = semget(key, nsems, 0666);
printf(&exit: semid is %d\n&, iSemId);
/* 进程同步执行 */
for(int i = 0; i & 10; ++i)
if(binary_semaphore_wait(iSemId))
perror(&semop: &);
printf(&%d &, getpid());
printf(&%d\n&, getpid());
if(binary_semaphore_post(iSemId))
&&/* posixSemProgessLock.cpp
Created on:
* Detail: 使用Posix信号量的进程同步
#include &stdio.h&
#include &stdlib.h&
#include &unistd.h&
#include &semaphore.h&
#include &fcntl.h&
#define SEM_NAME &0x&
int main()
/* 初始化一个有名二元信号灯
sem = sem_open(SEM_NAME, O_CREAT, 0666, 10);
if(sem == SEM_FAILED)
perror(&sem init failed:&);
return -1;
sem_wait(sem);
sem_getvalue(sem,&val);
printf(&1: getvalue: value=%d, pid=%d\n&,val, getpid());
printf(&2: getvalue: value=%d, pid=%d\n&,val, getpid());
sem_post(sem);
sem_getvalue(sem,&val);
printf(&3: getvalue: value=%d, pid=%d\n&,val, getpid());
sem_unlink(SEM_NAME);
PV原子操作主要用于进程或线程间的同步和互斥这两种典型情况。若用于互斥,几个进程(或线程)往往只设置一个信号量sem。 当信号量用于同步操作时,往往会设置多个信号量,并安排不同的初始值来实现它们之间的顺序执行,下面是一个线程同步的例子:
/*thread_sem.c*/
#include &stdio.h&
#include &stdlib.h&
#include &pthread.h&
#include &semaphore.h&
#include &unistd.h&
#define THREAD_NUMBER
/* 线程数 */
#define REPEAT_NUMBER
/* 每个线程中的小任务数 */
#define DELAY_TIME_LEVELS
/*小任务之间的最大时间间隔*/
sem_t sem[THREAD_NUMBER];
void *thrd_func(void *arg)
int thrd_num = (int)
int delay_time = 0;
int count = 0;
/* 进行P操作 */
sem_wait(&sem[thrd_num]);
printf(&Thread %d is starting\n&, thrd_num);
for (count = 0; count & REPEAT_NUMBER; count++)
delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
sleep(delay_time);
printf(&\tThread %d: job %d delay = %d\n&, thrd_num, count, delay_time);
printf(&Thread %d finished\n&, thrd_num);
pthread_exit(NULL);
int main(void)
pthread_t thread[THREAD_NUMBER];
int no = 0,
void * thrd_
srand(time(NULL));
for (no = 0; no & THREAD_NUMBER; no++)
sem_init(&sem[no], 0, 0);
sem_getvalue(&sem[no],&val);
printf(&val is %d\n&, val);
res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);
if (res != 0)
printf(&Create thread %d failed\n&, no);
exit(res);
printf(&Create treads success\n Waiting for threads to finish...\n&);
/* 对最后创建的线程的信号量进行V操作 */
sem_post(&sem[THREAD_NUMBER - 1]);
for (no = THREAD_NUMBER - 1; no &= 0; no--)
res = pthread_join(thread[no], &thrd_ret);
printf(&Thread %d joined\n&, no);
printf(&Thread %d join failed\n&, no);
/* 进行V操作 */
sem_post(&sem[(no + THREAD_NUMBER - 1) % THREAD_NUMBER]);
for (no = 0; no & THREAD_NUMBER; no++)
/* 删除信号量 */
sem_destroy(&sem[no]);
我的热门文章
即使是一小步也想与你分享

我要回帖

更多关于 linux system v信号量 的文章

 

随机推荐