基于内存的posix信号量用法
来源:互联网 发布:天刀捏脸数据女听风 编辑:程序博客网 时间:2024/06/18 18:35
posix信号量的两种形式
基于文件系统
不打算详细讲细节,提供两种模板,简单的用法
#include <semaphore.h>sem_t* sem_open(const char*name,int oflag,.../*mode_t mode,unsigned int value*/)
oflag参数我一般指定O_CREAT|O_RDWR,因为一般不保存信号量,毕竟总觉得这东西会一直占系统资源,所以我创建时指定O_CREAT,意思就是如果不存在和这个信号量,则创建并初始化它,若存在则为这个信号量重新赋值。一般程序退出时删除它。
mode参数可以参考man 2 open。我一般指定#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH),方便好用。
int sem_close(semt_t *sem);
注意,close一个信号量并没释放它的资源,posix信号量至少是随内核持续的,close只是“扯断这个信号量和进程的联系”。我们要真的删除某个信号量时,应该用
int sem_unlink(sem_t *sem);
删除仅当没有任何进程还打开这个信号量时成功
PV操作
int sem_wait(sem_t *sem);//p oprationint sem_post(sem_t *sem);//v opration
这就是操作系统课上讲的PV操作
demo
两个进程,mmap共享一个内存,通过信号量来管理这个共享内存。一个进程从stdin收取字符串,并写入共享内存,然后V信号量
另一个进程P信号量,拿走字符串,v信号量。输出到stdout。
发送程序输入exit,可以将接收程序终止
注意 编译时要链接 lrt或者lpthread
Send.c
#include <unistd.h>#include <stdio.h>#include <fcntl.h>#include <sys/mman.h>#include <stdlib.h>#include <string.h>#include <semaphore.h>#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)// void *mmap(void *addr, size_t length, int prot, int flags,// int fd, off_t offset);char buf[1024];int main(){ sem_t *mutex = sem_open("wudi_sem",O_CREAT|O_RDWR,FILE_MODE,0); int fd = open("0xabc",O_CREAT|O_RDWR,FILE_MODE); char *sharedFile = mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(!sharedFile) { perror("mmap:"); sem_unlink("wudi_sem"); exit(-1); } write(fd,buf,1024); close(fd); while(scanf("%s",buf)!=EOF) { memcpy(sharedFile,buf,128); sem_post(mutex); } sem_unlink("wudi_sem"); printf("unlink mutex\n"); return 0;}
Recv.c
#include <unistd.h>#include <sys/mman.h>#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <semaphore.h>#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)// void *mmap(void *addr, size_t length, int prot, int flags,// int fd, off_t offset);char buf[1024];int main(){ sem_t *mutex = sem_open("wudi_sem",O_RDWR); int fd = open("0xabc",O_RDWR); if(fd<0) { perror("open:"); exit(-1); } char *sharedFile = mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(!sharedFile) { perror("mmap:"); sem_unlink("wudi_sem"); exit(-1); } close(fd); while(1) { sem_wait(mutex); memcpy(buf,sharedFile,128); if(strcmp(buf,"exit")==0) { printf("ready to exit\n"); break; } printf("get msg>> %s\n",buf); } sem_unlink("wudi_sem"); printf("unlink mutex\n"); return 0;}
注意以上两个程序并未十分安全的处理临界区,send方对共享内存的写其实并不安全,因为可能recv方正在读取那个数据,正确的做法应该是将共享内存做成一个队列,这样写的位置和读的位置就能避免冲突。但此处仅作演示用,而且从stdin收东西其实很慢的。。。。。
基于共享内存的信号量
int sem_init(sem_t *sem,int shared,int value);int sem_destroy(sem_t *sem);
注意:
- sem的内存由调用者自己分配,并得确保这个内存一直存在
- 不要重复对一个信号量调用sem_init(),其结果是未定义的
- 不要copy信号量,使用copy后的信号量的副本,其结果是未定义的
- sem_init失败时返回-1,但成功时并不返回0
- 就算是在stack空间上分配的空间,也要在不使用时,调用sem_destroy释放资源
其中 shared 参数 指示是否在进程间共享
demo
将上一个例子改成基于共享内存的信号量
Send.c
#include <unistd.h>#include <stdio.h>#include <fcntl.h>#include <sys/mman.h>#include <stdlib.h>#include <string.h>#include <semaphore.h>#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)// void *mmap(void *addr, size_t length, int prot, int flags,// int fd, off_t offset);char buf[1024];int main(){ sem_t *mutex; //= sem_open("wudi_sem",O_CREAT|O_RDWR,FILE_MODE,0); char *dataStart; int fd = open("0xabc",O_CREAT|O_RDWR,FILE_MODE); char *sharedFile = mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(!sharedFile) { perror("mmap:"); sem_unlink("wudi_sem"); exit(-1); } write(fd,buf,1024); close(fd); mutex = (sem_t*)sharedFile; if(sem_init(mutex,1,0) < 0) { perror("mutex init"); exit(-1); } dataStart = (char*)sharedFile + sizeof(sem_t); while(scanf("%s",buf)!=EOF) { memcpy(dataStart,buf,128); sem_post(mutex); } sem_destroy(mutex); printf("exit\n"); return 0;}
Recv.c
#include <unistd.h>#include <sys/mman.h>#include <stdio.h>#include <fcntl.h>#include <string.h>#include <stdlib.h>#include <semaphore.h>#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)// void *mmap(void *addr, size_t length, int prot, int flags,// int fd, off_t offset);char buf[1024];int main(){ sem_t *mutex; //= sem_open("wudi_sem",O_RDWR); char *dataStart; int fd = open("0xabc",O_RDWR); if(fd<0) { perror("open:"); exit(-1); } char *sharedFile = mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(!sharedFile) { perror("mmap:"); sem_unlink("wudi_sem"); exit(-1); } close(fd); mutex = (sem_t*)sharedFile; //make sure there exist a sempahore at the start of sharedFile dataStart = (char*)sharedFile + sizeof(sem_t); while(1) { sem_wait(mutex); memcpy(buf,dataStart,128); if(strcmp(buf,"exit")==0) { printf("ready to exit\n"); break; } printf("get msg>> %s\n",buf); } sem_destroy(mutex); printf("exit\n"); return 0;}
阅读全文
0 0
- 基于内存的posix信号量用法
- Posix有名信号量、基于内存的信号量
- 关于Posix的信号量
- posix信号量对system V共享内存的同步控制
- posix 基于文件的共享内存
- posix 基于共享内存
- Linux下:POSIX内存对象映射+POSIX内存对象信号量
- Posix信号量
- POSIX信号量
- Posix信号量
- Posix信号量
- Posix信号量
- posix 信号量
- Posix信号量
- POSIX信号量
- POSIX信号量
- POSIX信号量
- POSIX 信号量
- hadoop学习笔记:创建maven项目与使用hdfs的读写API
- shell debug
- poj 1091 跳蚤(容斥原理)
- 剑指offer_二叉树---从上往下打印二叉树
- hdu 4344 Mark the Rope (质因子分解+米勒拉宾素性)
- 基于内存的posix信号量用法
- 应聘高校教师的试讲技巧
- 20170820考试总结
- React Native组件(四)TextInput组件解析
- 无法访问Eclipse启动的Tomcat容器中的项目
- Java的加密技术(BASE64与单向加密算法MD5,SHA,MAC)
- 关于近期爬虫学习的总结
- python:基于wxpy微信聊天机器人
- getByClass