POSIX
信号量分为两种,分别是
POSIX
无名信号量和
POSIX
有名信号量, 这两种信号量比之前介绍的 system-V
的信号量机制要简洁,虽然没有后者的应用范围那 么广泛(尤其在一些老系统中,因为 system-V
的信号量机制要更古老一些),但是
POSIX 良好的设计使得他们更具吸引力
POSIX 有名信号量
这种有名信号量的名字由类似“/somename”这样的字符串组成,注意前面有一个正 斜杠,这样的信号量其实是一个特殊的文件,创建成功之后将会被放置在系统的一个特殊的 虚拟文件系统/dev/shm
之中,不同的进程间只要约定好一个相同的名字,他们就可以通 过这种有名信号量来相互协调。
POSIX 有名信号量的一般使用步骤是:
1
,使用
sem_open( )
来创建或者打开一个有名信号量。
2
,使用
sem_wait( )
和
sem_post( )
来分别进行
P
操作和
V
操作。
3
,使用
sem_close( )
来关闭他。
4
,使用
sem_unlink( )
来删除他,并释放系统资源。
#include<stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
char * shm_init()
{
//获取KEY值
int key=ftok("./",'X');
int shm_id=shmget(key, 4096,IPC_CREAT|0666);
if(shm_id==-1)
{
perror("shmget id erorr");
exit(1);//直接结束进程
}
//映射共享内存
char *shm_map=shmat(shm_id, NULL, 0);
if(shm_map==(void *)-1)
{
perror("shm map error");
exit(1);//直接结束进程
}
return shm_map;
}
int main(int argc, char const *argv[])
{
//配置共享内存并初始化
char *shm_map=shm_init();
//初始化信号量int sem_id=sem_nameinit();
sem_t* fd_sem=sem_open("/my sem name", O_CREAT, 0644, 1); // 创建一个新的有名信号量 初始化资源为0
while (1)
{
//申请一个资源
printf("等待申请资源中!!\n");
sem_wait(fd_sem);
printf("成功申请到资源!!\n请输入消息:");
//写入信息到共享内存中
fgets(shm_map,4096,stdin);
sem_post(fd_sem);
}
return 0;
}
不像 system-V
的信号量可以申请或者释放超过
1
个资源,对于
POSIX 信号量而言,
每次申请和释放的资源数都是 1
。其中调用
sem_wait( )
在资源为
0 时会导致阻塞,如果
不想阻塞等待,可以使用 sem_trywait( )来替代。