进程间通信之信号量semaphore--linux内核剖析( 五 )
有名信号量相关函数说明有名信号量在使用的时候 , 和无名信号量共享sem_wait和sem_post函数 。区别是有名信号量使用sem_open代替sem_init , 另外在结束的时候要像关闭文件一样去关闭这个有名信号量 。
- 打开一个已存在的有名信号量 , 或创建并初始化一个有名信号量 。 一个单一的调用就完 成了信号量的创建、初始化和权限的设置 。
sem_t *sem_open(const char *name, int oflag, mode_t mode , int value);
参数描述name文件的路径名;Oflag有O_CREAT或O_CREATmode_t控制新的信号量的访问权限;Value指定信号量的初始化值 。注意:
这里的name不能写成/tmp/aaa.sem这样的格式 , 因为在linux下 , sem都是创建在/dev/shm目录下 。 你可以将name写成“/mysem”或“mysem” , 创建出来的文件都是“/dev/shm/sem.mysem” , 千万不要写路径 。 也千万不要写“/tmp/mysem”之类的 。
当oflag = O_CREAT时 , 若name指定的信号量不存在时 , 则会创建一个 , 而且后面的mode和value参数必须有效 。 若name指定的信号量已存在 , 则直接打开该信号量 ,
同时忽略mode和value参数 。
当oflag = O_CREAT|O_EXCL时 , 若name指定的信号量已存在 , 该函数会直接返回error 。
- 一旦你使用了一信号量 , 销毁它们就变得很重要 。在做这个之前 , 要确定所有对这个有名信号量的引用都已经通过sem_close()函数关闭了 , 然后只需在退出或是退出处理函数中调用sem_unlink()去删除系统中的信号量 ,注意如果有任何的处理器或是线程引用这个信号量 , sem_unlink()函数不会起到任何的作用 。
有名信号量在无相关进程间的同步前面已经说过 , 有名信号量是位于共享内存区的 , 那么它要保护的资源也必须是位于共享内存区 , 只有这样才能被无相关的进程所共享 。 在下面这个例子中 , 服务进程和客户进程都使用shmget和shmat来获取得一块共享内存资源 。 然后利用有名信号量来对这块共享内存资源进行互斥保护 。
服务器程序
//server.c#include #include #include #include #include #include #include #include #include #include #define SHMSZ 27char SEM_NAME[]= "vik";int main(){charch;intshmid;key_tkey;char*shm,*s;sem_t*mutex;//name the shared memory segmentkey = 1000;//createif(mutex == SEM_FAILED){perror("unable to create semaphore");sem_unlink(SEM_NAME);exit(-1);}//create the shared memory segment with this keyshmid = shmget(key, SHMSZ, IPC_CREAT | 0666);if(shmid < 0){perror("failure in shmget");exit(-1);}//attach this segment to virtual memoryshm = shmat(shmid, NULL, 0);//start writing into memorys = shm;for(ch = 'A'; ch <= 'Z'; ch++){sem_wait(mutex);*s++ = ch;sem_post(mutex);}//the below loop could be replaced by binary semaphorewhile(*shm != '*'){sleep(1);}sem_close(mutex);sem_unlink(SEM_NAME);shmctl(shmid, IPC_RMID, 0);return EXIT_SUCCESS;}
客户端程序// client.c#include #include #include #include #include #include #include #include #include #include #define SHMSZ 27char SEM_NAME[]= "vik";int main(){intshmid;key_tkey;char*shm, *s;sem_t*mutex;//name the shared memory segmentkey = 1000;//createif(mutex == SEM_FAILED){perror("reader:unable to execute semaphore");sem_close(mutex);exit(-1);}//create the shared memory segment with this keyshmid = shmget(key, SHMSZ, 0666);if(shmid < 0){perror("reader:failure in shmget");exit(-1);}//attach this segment to virtual memoryshm = shmat(shmid, NULL, 0);//start readings = shm;for(s = shm; *s != '\0'; s++){sem_wait(mutex);putchar(*s);sem_post(mutex);}//once done signal exiting of reader:This can be replaced by another semaphore*shm = '*';sem_close(mutex);shmctl(shmid, IPC_RMID, 0);return EXIT_SUCCESS;}
SYSTEM V信号量这是信号量值的集合 , 而不是单个信号量 。 相关的信号量操作函数由引用 。ystem V 信号量在内核中维护 , 其中包括二值信号量 、计数信号量、计数信号量集 。
- 二值信号量 : 其值只有0、1 两种选择 , 0表示资源被锁 , 1表示资源可用;
- 计数信号量:其值在0 和某个限定值之间 , 不限定资源数只在0 1 之间;
- 计数信号量集 :多个信号量的集合组成信号量集
struct semid_ds{struct ipc_perm sem_perm; /* 信号量集的操作许可权限 */struct sem *sem_base; /* 某个信号量sem结构数组的指针 , 当前信号量集中的每个信号量对应其中一个数组元素 */ushort sem_nsems; /* sem_base 数组的个数 */time_t sem_otime; /* 最后一次成功修改信号量数组的时间 */time_t sem_ctime; /* 成功创建时间 */};
- 通气会|12月4~6日,2020中国信息通信大会将在成都举行
- 中国|浅谈5G移动通信技术的前世和今生
- 星期一|亚马逊:黑五与网络星期一期间 第三方卖家销售额达到48亿美元
- 建设|龙元建设中标中国移动宁波信息通信产业园二期施工项目
- IPO|三旺通信IPO:产品结构相对单一业务规模较小 研发人员占员工总数33%
- 空间|垃圾文件正在吞噬你的C盘空间用这四种方法,还你一个干净的C盘
- 广告点击|广告效果评估:30天的广告时间评估最全面
- 要来|折叠屏iPhone终于要来了!可惜发布的时间有点晚,你愿意等吗?
- 智能手机品|越南手机悄然崛起!创立短短2年时间,在当地接连击退苹果、小米
- 科技|短视频行业领先 云想科技成长空间广阔