织梦CMS - 轻松建站从此开始!

罗索

生产者消费者问题

落鹤生 发布于 2010-04-01 21:44 点击:次 
经典的问题总是重现:"生产者-消费者",来一段完整实现的代码。
TAG:

 

  1. #include<sys/types.h> 
  2. #include<linux/sem.h> 
  3. #include<linux/shm.h> 
  4. #include<unistd.h> 
  5. #include<stdio.h> 
  6. #include<errno.h> 
  7. #include<time.h> 
  8.  
  9. #define MAXSHM 5 //定义缓冲区数组的下标变量个数 
  10.  
  11.  
  12. /*        定义3个信号量的内部标识 */ 
  13.  
  14. int fullid; 
  15. int emptyid; 
  16. int mutexid; 
  17.  
  18. /* 主函数 */ 
  19. int main() 
  20. /* 定义2个共享内存的ID */ 
  21. int arrayid; 
  22. int getid; 
  23. /* 定义共享内存虚拟地址 */ 
  24. int *array; 
  25. int *get; 
  26.     /* 创建共享内存 */ 
  27. arrayid=shmget(IPC_PRIVATE,sizeof(int) *MAXSHN,IPC_CREAT|0666); 
  28. getid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666); 
  29.     /* 初始化共享内存 */ 
  30. array=(int *) shmat(arrayid,0,0); 
  31. get=(int *) shmat(getid,0,0); 
  32. *get=0; 
  33.     /* 定义信号量数据结构 */ 
  34. struct sembuf P,V; 
  35. union semun arg; 
  36.     /* 创建信号量 */ 
  37. fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666); 
  38. emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666); 
  39. mutexid=semget(IPC_PRIVATE,1,IPC_CREAT|0666); 
  40.     /*初始化信号量 */ 
  41. arg.val=0;            //初始时缓冲区中无数据 
  42. if(semctl(fullid,0,SETVAL,arg)==-1) 
  43.    perror("semctl setval error"); 
  44. arg.val=MAXSHM;       //初始时缓冲区中有5个空闲的数组元素 
  45. if(semctl(emptyid,0,SETVAL,arg)==-1) 
  46.    perror("semctl setval error"); 
  47. arg.val=1;            //初始时互斥信号为1,允许一个进程进入 
  48. if(semctl(mutexid,0,SETVAL,arg)==-1) 
  49.         perror("semctl setval error"); 
  50.  
  51.     /* 初始化 P V操作 */ 
  52. P.sem_num=0; 
  53. P.sem_op=-1; 
  54. P.sem_flg=SEM_UNDO; 
  55.     V.sem_num=0; 
  56. V.sem_op=1; 
  57. V.sem_flg=SEM_UNDO; 
  58.  
  59.     /*   生产者进程 */ 
  60. if(fork()==0) 
  61.    int i=0; 
  62.    int set=0; 
  63.    while(i<10) 
  64.    { 
  65.     semop(emptyid,&P,1);         //对 emptyid执行P操作 
  66.     semop(mutexid,&P,1);         //对 mutexid执行 P操作 
  67.     array[set%MAXSHM]=i+1; 
  68.     printf("Producer put number %d to No.%d\n",array[set%MAXSHM],set%MAXSHM); 
  69.     set++;                       //写计数加1 
  70.     semop(mutexid,&V,1);         //对mutexid执行 V 操作 
  71.     semop(fullid,&V,1);          //对fullid执行 V 操作 
  72.     i++; 
  73.    } 
  74.    sleep(3);                    //SLEEP 3秒,等待消费者进程执行完毕 
  75.    printf("Poducer if over\n"); 
  76.    exit(0); 
  77. else 
  78.    /* 消费者A进程 */ 
  79.    if(fork()==0) 
  80.    { 
  81.     while(1) 
  82.     { 
  83.      if(*get==10) 
  84.       break
  85.      semop(fullid,&P,1);        //对fullid执行 P 操作 
  86.      semop(mutexid,&P,1);       //对mutexid执行 P 操作 
  87.      printf("The ConsumerA get number from No.%d\n",(*get)%MAXSHM); 
  88.      (*get)++;                   //读计数加1 
  89.      semop(mutexid,&V,1);        //对mutexid执行 V 操作 
  90.      semop(emptyid,&V,1);        //对fullid执行 V 操作 
  91.      sleep(1); 
  92.     } 
  93.     printf("ConsunerA is over\n"); 
  94.     exit(0); 
  95.    } 
  96.    else 
  97.    { 
  98.      /*消费者B进程 */ 
  99.     if(fork()==0) 
  100.     { 
  101.      while(1) 
  102.      { 
  103.       if(*get==10) 
  104.        break
  105.        semop(fullid,&P,1);       //对fullid执行 P 操作 
  106.      semop(mutexid,&P,1);      //对mutexid执行 P 操作 
  107.      printf("The ConsumerA get number from No.%d\n",(*get)%MAXSHM); 
  108.      (*get)++;                 //读计数加1 
  109.      semop(mutexid,&V,1);      //对mutexid执行 V 操作 
  110.      semop(emptyid,&V,1);      //对emptyid执行 V 操作 
  111.      sleep(1); 
  112.     } 
  113.     printf("ConsunerB is over\n"); 
  114.     exit(0); 
  115.     } 
  116.    } 
  117.  
  118. /*   父进程返回后回收3个子进程 */ 
  119. wait(0); 
  120. wait(0); 
  121. wait(0); 
  122.  
  123. /* 断开并撤消2个共享内存 */ 
  124. shmdt(array); 
  125. shmctl(arrayid,IPC_RMID,0); 
  126. shmctl(get); 
  127. shmctl(getid,IPC_RMID,0); 
  128. /*   撤消3个信号量集 */ 
  129. semctl(emptyid,IPC_RMID,0); 
  130. semctl(fullid,IPC_RMID,0); 
  131. semctl(mutexid,IPC_RMID,0); 
  132. exit(0); 

 

(落鹤生)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201004/8964.html]
本文出处:网络博客 作者:落鹤生
顶一下
(0)
0%
踩一下
(1)
100%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容