对信号集与信号量的理解

参考如下链接:http://www.c-lang.net/semctl/index.html 不过是日语的。

把他的程序重新改动一下,改为一次性为信号集合申请两个信号量:

代码变成:

#include <stdio.h>        

#include <unistd.h>        

#include <sys/wait.h>        

#include <stdlib.h>        

#include <sys/sem.h>        

#define LOCK -1        

#define UNLOCK 1        

        

/* semophore operation (lock/unlock) */        

void Semop01(int SemId,int Op);        



/* semophore operation (lock/unlock) */        

void Semop02(int SemId,int Op);        



int main()        

{        

      FILE               *fp01 ,  *fp02;    

      int                semid;    

        

      union semun {    

        int  val;   /* value for SETVAL*/    

        struct semid_ds  *buf;  /* buffer for IPC_STAT,IPC_SET using */

        unsigned short   *array; /* array for  GETALL,SETALL */    

      } ctl_arg;    

        

      char       *file01 = "./sem01.txt";    

      int           child_cnt01;    

      int           line_cnt01;    

      if ((fp01 = fopen(file01,"w")) == NULL) {    

            perror("main : fopen ");

            exit(EXIT_FAILURE);

      }           

      setvbuf(fp01,NULL,_IONBF,0);    

        

      char       *file02 = "./sem02.txt";    

      int           child_cnt02;    

      int           line_cnt02;    

      if ((fp02 = fopen(file02,"w")) == NULL) {    

            perror("main : fopen ");

            exit(EXIT_FAILURE);

      }    

 

      setvbuf(fp02,NULL,_IONBF,0);    

        

      /* to create one semophore array which hold two semophore */    

      if ((semid = semget(IPC_PRIVATE,2,0600)) == -1){    

            perror("main : semget ");

            exit(EXIT_FAILURE);

      }

/* initialize the first semophore with value 1*/    



      ctl_arg.val = 1;    

      if (semctl(semid,0,SETVAL,ctl_arg) == -1){    

            perror("main : semctl ");

            exit(EXIT_FAILURE);

      }    

        

      /* initialize the second semophore with value 1*/    

      ctl_arg.val = 1;    

      if (semctl(semid,1,SETVAL,ctl_arg) == -1){    

            perror("main : semctl ");

            exit(EXIT_FAILURE);

      }    

        

      /* fork three child process*/    

      for (child_cnt01 = 0; child_cnt01 < 3; ++child_cnt01) {    

        if (fork() == 0) {    



              /* child process */

              printf("child process %d begin\n",child_cnt01 + 1); 

              Semop01(semid,LOCK);            /*lock*/



              for (line_cnt01 = 1; line_cnt01 <= 5; ++line_cnt01) {

                fprintf(fp01,"child process %d  msg : %d\n",

                            child_cnt01 + 1,line_cnt01);

                sleep(1);

              }



              Semop01(semid,UNLOCK);          /* unlock*/

              printf("child process %d ends\n",child_cnt01 + 1);

              exit(EXIT_SUCCESS);

        }    

      }    



      /* fork another two child process*/

      for (child_cnt02 = 0; child_cnt02< 2; ++child_cnt02) {    

        if (fork() == 0) {    

              /* child process */

              printf("another child process %d begin\n",

                        child_cnt02 + 1);     



              Semop02(semid,LOCK);            /*lock*/        



              for (line_cnt02 = 1; line_cnt02 <= 5; ++line_cnt02) {

                fprintf(fp02,"another child process %d  msg : %d\n",

                          child_cnt02 + 1,line_cnt02);

                sleep(1);

              }

        

              Semop02(semid,UNLOCK);          /* unlock*/

        

              printf("another child process %d ends\n",child_cnt02 + 1);

              exit(EXIT_SUCCESS);

        }    

      }    

               

      /* parent process, waitint for  child process ending */    

      for (child_cnt01 = 0; child_cnt01 < 5; ++child_cnt01) {    

            wait(NULL);

      }    

        

      /* delete semophore array*/    

      if (semctl(semid,0,IPC_RMID,ctl_arg) == -1){    

            perror("main : semctl ");

            exit(EXIT_FAILURE);

      }    

                

      fclose(fp01);    

      fclose(fp02);

                

      printf("parenet process ends\n");    

      return EXIT_SUCCESS;    

        

}        

        

/* semophore operation (lock/unlock) */        

void Semop01(int p_semid,int p_op)        

{        

      struct sembuf    sops[1];    

        

      sops[0].sem_num = 0;                 /* semophore number*/    

      sops[0].sem_op = p_op;               /* semophore operation*/    

      sops[0].sem_flg = 0;                 /* operation flag*/    

        

      if (semop(p_semid,sops,1) == -1) {    

            perror("Semop01 ");

            exit(EXIT_FAILURE);

      } 



      return;    

}        

                

/* semophore operation (lock/unlock) */  

void Semop02(int p_semid,int p_op)  

{        

      struct sembuf    sops[2];    

          

      sops[0].sem_num=0;

      sops[0].sem_op=0;

      sops[0].sem_flg=0;

        

      sops[1].sem_num = 1;                 /* semophore number*/ 

      sops[1].sem_op = p_op;               /* semophore operation*/  

      sops[1].sem_flg = 0;                 /* operation flag*/    

        

      if (semop(p_semid,sops,2) == -1) { 

            perror("Semop02 ");

            exit(EXIT_FAILURE);

      }



      return;    

}        

 其中,三个子进程用第一个信号量,另外两个子进程用第二个信号量。互不干扰。

运行结果:

child process 1 begin
child process 2 begin
child process 3 begin
another child process 1 begin
another child process 2 begin
child process 1 ends
another child process 1 ends
child process 2 ends
another child process 2 ends
child process 3 ends
parenet process ends

文件内容:

[root@gaorhel01 gao]# cat sem01.txt
child process 1 msg : 1
child process 1 msg : 2
child process 1 msg : 3
child process 1 msg : 4
child process 1 msg : 5
child process 2 msg : 1
child process 2 msg : 2
child process 2 msg : 3
child process 2 msg : 4
child process 2 msg : 5
child process 3 msg : 1
child process 3 msg : 2
child process 3 msg : 3
child process 3 msg : 4
child process 3 msg : 5
[root@gaorhel01 gao]# cat sem02.txxt
cat: sem02.txxt: No such file or directory
[root@gaorhel01 gao]# cat sem02.txt
another child process 1 msg : 1
another child process 1 msg : 2
another child process 1 msg : 3
another child process 1 msg : 4
another child process 1 msg : 5
another child process 2 msg : 1
another child process 2 msg : 2
another child process 2 msg : 3
another child process 2 msg : 4
another child process 2 msg : 5

你可能感兴趣的:(信号量)