免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2401 | 回复: 0
打印 上一主题 下一主题

[学习] linux了解信号量机制,了解并掌握进程同步和互斥机制 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-06-06 11:07 |只看该作者 |倒序浏览
本帖最后由 esolodo 于 2013-06-06 11:07 编辑

目的:了解信号量机制,了解并掌握进程同步和互斥机制,熟悉信号量的操作函数,利用信号量实现对共享资源的控制。 
设计要求:编程模拟实现这一问题的程序控制,分析处理过程, 
问题描述:桌子上有一只盘子,最多可容纳两个水果,每次只能放入或取出一个水果。爸爸专向盘子放苹果(apple),妈妈专向盘子中放桔子(orange);两个儿子专等吃盘子中的桔子,两个女儿专等吃盘子中的苹果。请用P、V操作来实现爸爸、妈妈、儿子、女儿之间的同步与互


  1. #include<stdio.h>
  2. #include<unistd.h>
  3. #include<sys/shm.h>
  4. #include<sys/types.h>
  5. #include<sys/ipc.h>
  6. #include<sys/sem.h>


  7. struct dish
  8. {//盘子
  9.         int total_num;//苹果和句子的总个数
  10.         int apple;//苹果的个数
  11.         int orang;//橘子的个数
  12. };
  13. typedef struct dish dish;

  14. union semun
  15. {
  16.         int val;
  17.         struct semid_ds *buf;
  18.         unsigned short *array;
  19. };

  20. int init_sem(int sem_id,int init_val)
  21. {// 将信号量sem_id设置为init_value
  22.         union semun sem_union;
  23.         sem_union.val=init_val;
  24.         if(semctl(sem_id,0,SETVAL,sem_union) == -1)
  25.         {
  26.                 printf("semctl init error\n");
  27.                 exit(1);
  28.         }
  29.         return 0;
  30. }
  31. int del_sem(int sem_id)
  32. {// 删除sem_id信号量
  33.         union semun sem_union;
  34.         if((semctl(sem_id,0,IPC_RMID,sem_union)) == -1)
  35.         {
  36.                 perror("sem delete");
  37.                 exit(1);
  38.         }
  39.         return 0;
  40. }
  41. int sem_p(int sem_id)
  42. {// 对sem_id执行p操作
  43.         struct sembuf sem_buf;
  44.         sem_buf.sem_num = 0;//信号量编号
  45.         sem_buf.sem_op = -1;//P操作
  46.         sem_buf.sem_flg = SEM_UNDO;//系统退出前未释放信号量,系统自动释放
  47.         if(semop(sem_id,&sem_buf,1) == -1)
  48.         {
  49.                 perror("sem p operation");
  50.                 exit(1);
  51.         }
  52.         return 0;
  53. }
  54. int sem_v(int sem_id)
  55. {// 对sem_id执行V操作
  56.         struct sembuf sem_buf;
  57.         sem_buf.sem_num = 0;
  58.         sem_buf.sem_op = 1;//V操作
  59.         sem_buf.sem_flg = SEM_UNDO;
  60.         if(semop(sem_id,&sem_buf,1) == -1)
  61.         {
  62.                 perror("sem v operation");
  63.                 exit(1);
  64.         }
  65.         return 0;
  66. }

  67. int main()
  68. {
  69.         pid_t temp;
  70.         pid_t mother;
  71.         pid_t father;
  72.         pid_t son;
  73.         pid_t daughter;

  74.         dish *dishs;
  75.         int shmid;//共享区域
  76.         int sem_id;//信号量
  77.         key_t sem_key;

  78.         sem_key = ftok(".",'a');
  79.          //    以0666且create mode创建一个信号量,返回给sem_id
  80.         sem_id = semget(sem_key,1,0666|IPC_CREAT);
  81.         init_sem(sem_id,1);//    将sem_id设为1

  82.         if((shmid = shmget(IPC_PRIVATE,sizeof(dish),IPC_CREAT|0666)) < 0)
  83.         {//获得共享区域号
  84.                 printf("shmget error!\n");
  85.                 exit(1);
  86.         }
  87.         if((dishs = (dish*)shmat(shmid,0,0)) == (int*) -1)
  88.         {//设置共享区域
  89.                 printf("shmat error\n");
  90.                 exit(1);
  91.         }

  92.         //初始化盘子
  93.         dishs->total_num = 0;
  94.         dishs->apple = 0;
  95.         dishs->orang = 0;
  96.        
  97.         //创建 妈妈、爸爸、儿子、女儿进程
  98.         if((mother = fork()) < 0)
  99.                         printf("fork()mother prosess error\n");
  100.         if((father = fork()) < 0)
  101.                 printf("fork() father prosess error\n");
  102.         if((son = fork())< 0)
  103.                 printf("fork() son prosess error\n");
  104.         if((daughter = fork()) < 0)
  105.                 printf("fork() daughter prosess error\n");
  106.         temp = getpid();
  107.         if(temp == 0)
  108.         {
  109.                 printf("this is mian----------------------------\n");
  110.                 printf("The nunber of apples = %d\n",dishs->apple);
  111.                 printf("The number of orang = %d \n",dishs->orang);
  112.         }else if(temp = mother)
  113.         {//妈妈放橘子

  114.                 if(!sem_p(sem_id))
  115.                 {//申请进入盘子放橘子,申请不成功则休眠
  116.                 printf("this is mother-----------------------------\n");
  117.                 printf("The nunber of apples = %d\n",dishs->apple);
  118.                 printf("The number of orang = %d \n",dishs->orang);
  119.                         if(dishs->total_num < 2)
  120.                         {//如果盘子满了,则装不下,就放弃等盘子有容量
  121.                                 dishs->orang++;
  122.                                 dishs->total_num++;
  123.                                 printf("Mama put a orange to the dish\n");
  124.                         }else
  125.                                 printf("This dish is full!\n");
  126.                 }
  127.                 sem_v(sem_id);//释放信号量
  128.                 sleep(1);
  129.         }else if(temp == father)
  130.         {//爸爸放苹果
  131.                 if(!sem_p(sem_id))
  132.                 {//申请进入盘子放苹果,申请不成功则休眠
  133.                 printf("this is father-----------------------------\n");
  134.                 printf("The nunber of apples = %d\n",dishs->apple);
  135.                 printf("The number of orang = %d \n",dishs->orang);

  136.                         if(dishs->total_num < 2)
  137.                         {//如果盘子满了,则装不下,就放弃等盘子有容量
  138.                                 dishs->apple++;
  139.                                 dishs->total_num++;
  140.                                 printf("Baba put a apple to the dish\n");
  141.                         }else
  142.                                 printf("The dish is full!\n");
  143.                 }
  144.                 sem_v(sem_id);//释放信号量
  145.                 sleep(1);
  146.         }else if(temp == son)
  147.         {//儿子吃橘子
  148.                 if(!(sem_p(sem_id)))
  149.                 {//申请进入盘子吃橘子,申请不成功则休眠
  150.                 printf("this is son ------------------------------\n");
  151.                 printf("The nunber of apples = %d\n",dishs->apple);
  152.                 printf("The number of orang = %d \n",dishs->orang);
  153.                         if(dishs->total_num > 0 && dishs->orang > 0)
  154.                         {//如果盘子里没有苹果则等待爸爸放苹果
  155.                                 dishs->total_num--;
  156.                                 dishs->orang--;
  157.                                 printf("The son eat a orange!\n");
  158.                         }else
  159.                                 printf("The son have no orange to eat\n");
  160.                         sem_v(sem_id);//释放信号量
  161.                         sleep(1);
  162.                 }
  163.         }else if(temp == daughter)
  164.         {//女儿吃苹果
  165.                 if(!sem_p(sem_id))
  166.                 {//申请进入盘子吃苹果,申请不成功则休眠
  167.                 printf("This is daughter---------------------------------\n");
  168.                 printf("The nunber of apples = %d\n",dishs->apple);
  169.                 printf("The number of orang = %d \n",dishs->orang);
  170.                         if(dishs->total_num > 0 && dishs->apple > 0)
  171.                         {//如果盘子里没有橘子,则女儿等待妈妈放橘子
  172.                                 dishs->total_num--;
  173.                                 dishs->apple--;
  174.                                 printf("The duaghter eat a apple!\n");
  175.                         }else
  176.                                 printf("The duaghter have no apple to eat\n");
  177.                         sem_v(sem_id);//释放信号量
  178.                         sleep(1);
  179.                 }
  180.         }

  181.         return 0;
  182. }






























复制代码
斥关系。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP