+ -
当前位置:首页 → 问答吧 → 请问semop如何保证进程互斥访问临界区

请问semop如何保证进程互斥访问临界区

时间:2010-08-26

来源:互联网

如果加上P ,V操作后,一个进程都打印完临界区所有内容后,另一个进程才会打印。
P,V操作可以保证多个进程对临界区的互斥访问这没错,但是本程序中,其实fork后的每个子进程都单一的在访问自己的临界区而已。
我现在不明白semop操作如何保证子进程在临界区访问时不受其他子进程的干扰,因为这不是多个进程共同访问一个临界区。
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/ipc.h>
  4. #include <sys/sem.h>
  5. #include <stdlib.h>
  6. union semun
  7. {
  8.         int val;
  9.         struct semid_ds *buf;
  10.         unsigned short int *array;
  11. };

  12. int p(int semid,int index)
  13. {
  14.         struct sembuf buf={0,-1,SEM_UNDO};

  15.         if(index<0)
  16.         {
  17.                 printf("error:index of the semaphore is invalid\n");
  18.                 exit(1);
  19.         }
  20.         buf.sem_num=index;
  21.         if(semop(semid,&buf,1)==-1)
  22.         {
  23.                 printf("P operation failed\n");
  24.                 exit(1);
  25.         }
  26.         return 0;
  27. }

  28. int v(int semid,int index)
  29. {
  30.         struct sembuf buf={0,+1,SEM_UNDO};

  31.         if(index<0)
  32.         {
  33.                 printf("error:index of the semaphore is invalid\n");
  34.                 exit(1);
  35.         }
  36.         buf.sem_num=index;
  37.         if(semop(semid,&buf,1)==-1)
  38.         {
  39.                 printf("V operation failed\n");
  40.                 exit(1);
  41.         }
  42.         return 0;
  43. }

  44. int main(int argc,char** argv)
  45. {
  46.         int proj_id;
  47.         int semid;
  48.         union semun arg;
  49.         pid_t pid;
  50.         key_t key;
  51.         int num;
  52.         int i,j;

  53.         if(argc!=2)
  54.         {
  55.                 printf("error:%s num\n",argv[0]);
  56.                 return -1;
  57.         }

  58.         num=atoi(argv[1]);

  59.         //create key
  60.         proj_id=2;
  61.         if((key=ftok(".",proj_id))==-1)
  62.         {
  63.                 printf("generating IPC key failed\n");
  64.                 return -1;
  65.         }

  66.         //create a semaphore set
  67.         if((semid=semget(key,1,IPC_CREAT|0666))==-1)
  68.         {
  69.                 printf("creating semaphore set failed\n");
  70.                 return -1;
  71.         }

  72.         if(semctl(semid,0,SETVAL,1)==-1)
  73.         {
  74.                 printf("set semval failed\n");
  75.                 return -1;
  76.         }

  77.         for(i=0;i<num;i++)
  78.         {
  79.                 pid=fork();
  80.                 if(pid<0)
  81.                 {
  82.                         printf("creating new process failed\n");
  83.                         return -1;
  84.                 }
  85.                 else if(pid==0)
  86.                 {
  87.                         if((semid=semget(key,1,0))==-1)
  88.                         {
  89.                                 printf("geting semid failed in the child process\n");
  90.                                 return -1;
  91.                         }

  92.                         p(semid,0);
  93.                         printf("===process %d enter the critical section===\n",getpid());
  94.                            sleep(1);
  95.                         printf("===process:%d is accessing=================\n",getpid());
  96.                         sleep(1);
  97.                         printf("===process %d leave the critical section===\n",getpid());
  98.                         sleep(1);
  99.                         v(semid,0);

  100.                         return -1;
  101.                 }
  102.         }

  103.         for(i=0;i<num;i++)
  104.         {
  105.                 wait(NULL);
  106.         }

  107.         if(semctl(semid,0,IPC_RMID,0)==-1)
  108.         {
  109.                 printf("remove the sem set failed\n");
  110.                 return -1;
  111.         }

  112.         return 0;
  113. }
复制代码

作者: edsionte   发布时间: 2010-08-26

为什么“不是同一个临界区”?

作者: drangon   发布时间: 2010-08-26