Linux高级进程间通信:信号量

来源:互联网 发布:中国金融大数据 编辑:程序博客网 时间:2024/06/15 17:42

父进程产生三个子进程,每一个都使用p()和v()来阻止其他进程在同一时刻执行一段关键区域。

 

 

pv.h:

/*semaphore exapmle header file */#include<stdlib.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/sem.h>#include<errno.h>#define SEMPERM   0600#define  FALSE     0#define   TRUE    1/* use typedef so we can do like this:{semun mymun;} *//*to define a union */typedef union _semun{    int val;    struct semid_ds *buf;   ushort *array;}semun;


 

initsem.c:

#include "pv.h"/*initsem----semaphore initialization */int initsem(key_t semkey){    int status=0,semid;      if((semid=semget(semkey,1,SEMPERM|IPC_CREAT|IPC_EXCL))==-1)    {         if(errno==EEXIST)//if exist,get the semkey         {               semid=semget(semkey,1,0);         }  } /*if create succeeded*/     else {      semun arg;//define a semun union    arg.val=1;//1 sem    status=semctl(semid,0,SETVAL,arg);//the index begin from 0表示只有一个信号量  }   if(semid==-1||status==-1)   {      perror("initsem failed");         return (-1);  }   /*all OK */  return (semid);}


 

 

 

p.c:

 

/*p.c---semaphore p operation--wait*/#include "pv.h"int p(int semid){    struct sembuf p_buf;   p_buf.sem_num=0;//include a sem   p_buf.sem_op=-1;    //p,wait  p_buf.sem_flg=SEM_UNDO;//undo表示进程退出时抵消对信号量的影响,因此所有进程退出后信号值的初值还是一样的    if(semop(semid,&p_buf,1)==-1)//1 means??only have a struct?   {   perror("P(semid) failed");      exit (1);  }   return (0);}


 

 

v.c:

 

/*v.c----semaphore v operation--signal */#include "pv.h"int v(int semid){   struct sembuf v_buf;   v_buf.sem_num=0;//1 sem   v_buf.sem_op=1;//v signal  v_buf.sem_flg=SEM_UNDO;//undo  if(semop(semid,&v_buf,1)==-1)   {      perror("v(semid)failed");   exit (1);  }   return (0);}


 

 

testsem.c:

 

/* testsem.c----test semaphore routines */#include "pv.h"#include<stdio.h>void handlesem(key_t skey);int main(void){   key_t semkey=0x200;    int i;  for(i=0;i<3;i++) //create three process  {       if(fork()==0)//child        {          handlesem(semkey);   }   }   return 0;}void handlesem(key_t skey){   int semid;  pid_t pid=getpid();//get pid if((semid=initsem(skey))<0)//initialize sem   {       exit (1);  }   printf("/nprocess %d before critical section /n",pid);    p(semid);  printf("process %d in critical section /n",pid);  /* do something when wait succeeded  *     *     *     *     *     */  sleep(5);   printf("process %d leaving critical section/n",pid);  v(semid);printf("process %d exiting /n",pid); exit (0);}


 

 

运行结果:
jiang@jiang-linux:~/unixprog/2011324$ gcc initsem.c p.c v.c testsem.c -o testsem.o;./testsem.o
process 2731 before critical section
process 2731 in critical section

process 2732 before critical section

process 2733 before critical section
process 2731 leaving critical section
process 2731 exiting
process 2732 in critical section
process 2732 leaving critical section
process 2732 exiting
process 2733 in critical section
process 2733 leaving critical section
process 2733 exiting

原创粉丝点击