众所周知,进程间通讯有三种方式,信号量、消息队列和共享内存。不过信号量我的感受不像通讯,其实就是一个锁的东西。html
这部份内容分几个部分数据结构
1.API函数
建立信号量 int semget(key_t key,int nsems,int semflg); 返回值就是信号量标识semid spa
Sem_op
|
操 做
|
正数
|
释放相应的资源数,将sem_op的值加到信号量的值上
|
0
|
进程阻塞直到信号量的相应值为0,当信号量已经为0,函数当即返回。若是信号量的值不为0,则依据sem_flg的IPC_NOWAIT位决定函数动做。sem_flg指定IPC_NOWAIT,则semop函数出错返回EAGAIN。sem_flg没有指定IPC_NOWAIT,则将该信号量的semncnt值加1,而后进程挂起直到下述状况发生。信号量值为0,将信号量的semzcnt的值减1,函数semop成功返回;此信号量被删除(只有超级用户或建立用户进程拥有此权限),函数smeop出错返回EIDRM;进程捕捉到信号,并从信号处理函数返回,在此状况将此信号量的semncnt值减1,函数semop出错返回EINTR
|
负数
|
请求sem_op的绝对值的资源。若是相应的资源数能够知足请求,则将该信号量的值减去sem_op的绝对值,函数成功返回。当相应的资源数不能知足请求时,这个操做与sem_flg有关。sem_flg指定IPC_NOWAIT,则semop函数出错返回EAGAIN。sem_flg没有指定IPC_NOWAIT,则将该信号量的semncnt值加1,而后进程挂起直到下述状况发生:当相应的资源数能够知足请求,该信号的值减去sem_op的绝对值。成功返回;此信号量被删除(只有超级用户或建立用户进程拥有此权限),函数smeop出错返回EIDRM:进程捕捉到信号,并从信号处理函数返回,在此状况将此信号量的semncnt值减1,函数semop出错返回EINTR
|
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/types.h> #include <sys/sem.h> union semun//因为类型是union 须要在这里初始化一下 { int val; struct semid_ds *buf; unsigned short int *array; struct seminfo *__buf; }; int main(int argc, char const *argv[]) { int semid; key_t key; key=ftok(".",3); //ftok的做用就是计算一个key值供使用,通常用当前目录文件结点索引号来计算,如指定文件的索引节点号为65538,换算成16进制为0x10002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x2610002。 semid=semget(key,1,IPC_CREAT|0666);//建立并获得信号量id if(semid==-1){ perror("semget"); exit(1); } printf("my semid is %d \n",semid); struct sembuf sbuf={0,-1,IPC_NOWAIT};// 上面sembuf结构体介绍中说,当sem_op=负数,请求sem_op的绝对值的资源。若是相应的资源数能够知足请求,则将该信号量的值减去sem_op的绝对值,函数成功返回。当相应的资源数不能知足请求时,这个操做与sem_flg有关。sem_flg指定IPC_NOWAIT,则semop函数出错返回EAGAIN。 union semun semopts; semopts.val=5; //对val赋值 if((semctl(semid,0,SETVAL,semopts))==-1){ // SETVAL就是给semun.val赋值的动做 perror("semctl"); exit(1); } printf("%s\n","ke" ); while(1){ if(semop(semid,&sbuf,1)==-1) // 这个操做就是semop来对{0,-1,IPC_NOWAIT}对应的动做 不断-1,直到=0 exit(1); sleep(3); } return 0; }
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/types.h> #include <sys/sem.h> int main(int argc, char const *argv[]) { int semid,semval; key_t key; key=ftok(".",3); //必须仍然用这两个值计算,否则信号量对应不起来,固然前提是两个代码位于相同的路径下 semid=semget(key,1,IPC_CREAT|0666); if(semid==-1){ perror("semget"); exit(1); } int val; while(1){ if((semval=semctl(semid,0,GETVAL,0))==-1)//GETVAL获得semun.val值 exit(1); if(semval>0) printf("val is %d\n",semval); else{ printf("stop!\n"); break; } sleep(3); } return 0; }结果:
val is 4 val is 3 val is 2 val is 1 stop!两个进程确实通讯成功。