标签:
信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步等功能。
当请求一个使用信号量来表示的资源时,进程需要先读取信号量的值来判断资源是否可用。大于0,资源可以请求,等于0,无资源可用,进程会进入睡眠状态直至资源可用。
当进程不再使用一个信号量控制的共享资源时,信号量的值+1,对信号量的值进行的增减 操作均为原子操作,这是由于信号量主要的作用是维护资源的互斥或多进程的同步访问。 而在信号量的创建及初始化上,不能保证操作均为原子性。
这里主要讨论二进制信号量。
由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的:P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.
前两个参数与前面一个函数中的一样,command通常是下面两个值中的其中一个SETVAL:用来把信号量初始化为一个已知的值。p 这个值通过union semun中的val成员设置,其作用是在信号量第一次使用前对它进行设置。IPC_RMID:用于删除一个已经无需继续使用的信号量标识符。
查看信号量:ipcs -s删除信号量:ipcrm -s sem_id(信号量id)
#include "comm.h"int main(){//int sem_id = create_sem_set(1);//init_sem_set(sem_id,0,1);pid_t id =fork();if(id < 0){perror("fork");return -1;}if(id == 0){//child// int c_sem_id = get_sem_set();while(1){//P(c_sem_id,0);printf("A");fflush(stdout);usleep(rand()%12345);printf("A");fflush(stdout);usleep(rand()%12354);//V(c_sem_id ,0);}}else{//fatherwhile(1){//P(sem_id,0);printf("B");fflush(stdout);usleep(rand()%123455);printf("B");fflush(stdout);usleep(rand()%123564);//V(sem_id ,0);}wait(NULL);//destory_sem_set(sem_id);}return 0;}
#include "comm.h"int main(){int sem_id = create_sem_set(1);init_sem_set(sem_id,0,1);pid_t id =fork();if(id < 0){perror("fork");return -1;}if(id == 0){//childint c_sem_id = get_sem_set();while(1){P(c_sem_id,0);printf("A");fflush(stdout);usleep(rand()%12345);printf("A");fflush(stdout);usleep(rand()%12354);V(c_sem_id ,0);}}else{//fatherwhile(1){P(sem_id,0);printf("B");fflush(stdout);usleep(rand()%123455);printf("B");fflush(stdout);usleep(rand()%123564);V(sem_id ,0);}wait(NULL);destory_sem_set(sem_id);}return 0;}
标签:
原文地址:http://blog.csdn.net/leetcode8023/article/details/52021201