IPC标识符和关键字:
在终端输入ipcs,可以看到目前系统中所有的IPC信息:
第一列的key就是IPC的关键字,第二列是IPC的标识符。
ftok()函数用于获得一个IPC的关键字,其函数原型是:
key_t ftok(const char *pathname,int proj_id);
下面是一个信号量的综合实例:
#include <stdio.h>测试这个程序,需要分别在两个终端进行操作。现在第一个终端运行程序,并选择2申请资源。
#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)
#else
union semun{
int val;
struct semid_ds *bur;
unsigned short *array;
struct seminfo *_but;
};
#endif
int 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;
}
屏幕输出如下:
进程创建了一个ID为65536的信号量集,并申请了一个资源。
我们从另一个终端输入ipcs 命令可以查看到这个信号量集:
在另一个终端在执行这个程序,把信号量ID作为参数传入:
选择2,这事进程会被阻塞,直到另一个进程把资源释放掉,切到另一个终端,输入1,此时可以看到第二个终端的程序马上申请到了资源。