进程间通信—信号量

来源:互联网 发布:光晕2windows live id 编辑:程序博客网 时间:2024/06/07 18:41

IPC标识符和关键字:

在终端输入ipcs,可以看到目前系统中所有的IPC信息:


第一列的key就是IPC的关键字,第二列是IPC的标识符。

ftok()函数用于获得一个IPC的关键字,其函数原型是:

key_t  ftok(const char *pathname,int proj_id);


下面是一个信号量的综合实例:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <errno.h>#include <sys/shm.h>#if defined(_GNU_LIBRARY_)&&!defined(_SEM_SEMUN_UNDEFINED)#elseunion semun{int val;struct semid_ds *bur;unsigned short *array;struct seminfo *_but;};#endifint semheld=0;int id=0;void pid_printf(char *format,...){va_list ap;va_start(ap,format);printf("[%d]:",getpid());vprintf(format,ap);}void sem_release(int id){struct sembuf sb;if(semheld < 1){pid_printf("I don't have any reources,nothing to release\n");return;}sb.sem_num=0;sb.sem_op=1;sb.sem_flg=SEM_UNDO;if(semop(id,&sb,1) == -1){pid_printf("Semop release error:%s\n",strerror(errno));exit(-1);}semheld--;pid_printf("Resource released.\n");}void sem_request(int id){struct sembuf sb;if(semheld > 0){pid_printf("I already hold the resource; not requesting another one.\n");return;}sb.sem_num=0;sb.sem_op=-1;sb.sem_flg=SEM_UNDO;pid_printf("Requesting resource...");fflush(stdout);if(semop(id,&sb,1) == -1){pid_printf("Semop request error:%s\n",strerror(errno));exit(-1);}semheld++;printf("Done...\n");}void sem_delete(void){printf("Master exiting ; delete semaphore.\n");if(semctl(id,0,IPC_RMID,0) == -1){pid_printf("Error releasing semaphore.\n");}}int main(int argc,char **argv){union semun sunion;if(argc <2){id=semget(IPC_PRIVATE,1,SHM_R|SHM_W);if(id != -1){atexit(sem_delete);sunion.val=3;if(semctl(id,0,SETVAL,sunion) == -1){pid_printf("semctl failed:%s\n",strerror(errno));exit(-1);}}}else{id=atoi(argv[1]);pid_printf("Using existing semaphore %d.\n",id);}if(id == -1){pid_printf("Semaphore request failed:%s.\n",strerror(errno));return 0;}pid_printf("Sucessfully allocated semaphore id %d.\n",id);while(1){int action;printf("\nStatus:%d request held by this process.\n",semheld);printf("please selesct:\n");printf("1. Release a resource\n");printf("2. Request a resource\n");printf("3. Exit this process\n");printf("Your choice:");scanf("%d",&action);switch(action){case 1:sem_release(id);break;case 2:sem_request(id);break;case 3:exit(0);break;}}return 0;}
测试这个程序,需要分别在两个终端进行操作。现在第一个终端运行程序,并选择2申请资源。

屏幕输出如下:



进程创建了一个ID为65536的信号量集,并申请了一个资源。

我们从另一个终端输入ipcs 命令可以查看到这个信号量集:


在另一个终端在执行这个程序,把信号量ID作为参数传入:


选择2,这事进程会被阻塞,直到另一个进程把资源释放掉,切到另一个终端,输入1,此时可以看到第二个终端的程序马上申请到了资源。


原创粉丝点击