- 论坛徽章:
- 0
|
本帖最后由 esolodo 于 2013-06-06 11:07 编辑
目的:了解信号量机制,了解并掌握进程同步和互斥机制,熟悉信号量的操作函数,利用信号量实现对共享资源的控制。
设计要求:编程模拟实现这一问题的程序控制,分析处理过程,
问题描述:桌子上有一只盘子,最多可容纳两个水果,每次只能放入或取出一个水果。爸爸专向盘子放苹果(apple),妈妈专向盘子中放桔子(orange);两个儿子专等吃盘子中的桔子,两个女儿专等吃盘子中的苹果。请用P、V操作来实现爸爸、妈妈、儿子、女儿之间的同步与互
- #include<stdio.h>
- #include<unistd.h>
- #include<sys/shm.h>
- #include<sys/types.h>
- #include<sys/ipc.h>
- #include<sys/sem.h>
- struct dish
- {//盘子
- int total_num;//苹果和句子的总个数
- int apple;//苹果的个数
- int orang;//橘子的个数
- };
- typedef struct dish dish;
- union semun
- {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- };
- int init_sem(int sem_id,int init_val)
- {// 将信号量sem_id设置为init_value
- union semun sem_union;
- sem_union.val=init_val;
- if(semctl(sem_id,0,SETVAL,sem_union) == -1)
- {
- printf("semctl init error\n");
- exit(1);
- }
- return 0;
- }
- int del_sem(int sem_id)
- {// 删除sem_id信号量
- union semun sem_union;
- if((semctl(sem_id,0,IPC_RMID,sem_union)) == -1)
- {
- perror("sem delete");
- exit(1);
- }
- return 0;
- }
- int sem_p(int sem_id)
- {// 对sem_id执行p操作
- struct sembuf sem_buf;
- sem_buf.sem_num = 0;//信号量编号
- sem_buf.sem_op = -1;//P操作
- sem_buf.sem_flg = SEM_UNDO;//系统退出前未释放信号量,系统自动释放
- if(semop(sem_id,&sem_buf,1) == -1)
- {
- perror("sem p operation");
- exit(1);
- }
- return 0;
- }
- int sem_v(int sem_id)
- {// 对sem_id执行V操作
- struct sembuf sem_buf;
- sem_buf.sem_num = 0;
- sem_buf.sem_op = 1;//V操作
- sem_buf.sem_flg = SEM_UNDO;
- if(semop(sem_id,&sem_buf,1) == -1)
- {
- perror("sem v operation");
- exit(1);
- }
- return 0;
- }
- int main()
- {
- pid_t temp;
- pid_t mother;
- pid_t father;
- pid_t son;
- pid_t daughter;
- dish *dishs;
- int shmid;//共享区域
- int sem_id;//信号量
- key_t sem_key;
- sem_key = ftok(".",'a');
- // 以0666且create mode创建一个信号量,返回给sem_id
- sem_id = semget(sem_key,1,0666|IPC_CREAT);
- init_sem(sem_id,1);// 将sem_id设为1
- if((shmid = shmget(IPC_PRIVATE,sizeof(dish),IPC_CREAT|0666)) < 0)
- {//获得共享区域号
- printf("shmget error!\n");
- exit(1);
- }
- if((dishs = (dish*)shmat(shmid,0,0)) == (int*) -1)
- {//设置共享区域
- printf("shmat error\n");
- exit(1);
- }
- //初始化盘子
- dishs->total_num = 0;
- dishs->apple = 0;
- dishs->orang = 0;
-
- //创建 妈妈、爸爸、儿子、女儿进程
- if((mother = fork()) < 0)
- printf("fork()mother prosess error\n");
- if((father = fork()) < 0)
- printf("fork() father prosess error\n");
- if((son = fork())< 0)
- printf("fork() son prosess error\n");
- if((daughter = fork()) < 0)
- printf("fork() daughter prosess error\n");
- temp = getpid();
- if(temp == 0)
- {
- printf("this is mian----------------------------\n");
- printf("The nunber of apples = %d\n",dishs->apple);
- printf("The number of orang = %d \n",dishs->orang);
- }else if(temp = mother)
- {//妈妈放橘子
- if(!sem_p(sem_id))
- {//申请进入盘子放橘子,申请不成功则休眠
- printf("this is mother-----------------------------\n");
- printf("The nunber of apples = %d\n",dishs->apple);
- printf("The number of orang = %d \n",dishs->orang);
- if(dishs->total_num < 2)
- {//如果盘子满了,则装不下,就放弃等盘子有容量
- dishs->orang++;
- dishs->total_num++;
- printf("Mama put a orange to the dish\n");
- }else
- printf("This dish is full!\n");
- }
- sem_v(sem_id);//释放信号量
- sleep(1);
- }else if(temp == father)
- {//爸爸放苹果
- if(!sem_p(sem_id))
- {//申请进入盘子放苹果,申请不成功则休眠
- printf("this is father-----------------------------\n");
- printf("The nunber of apples = %d\n",dishs->apple);
- printf("The number of orang = %d \n",dishs->orang);
- if(dishs->total_num < 2)
- {//如果盘子满了,则装不下,就放弃等盘子有容量
- dishs->apple++;
- dishs->total_num++;
- printf("Baba put a apple to the dish\n");
- }else
- printf("The dish is full!\n");
- }
- sem_v(sem_id);//释放信号量
- sleep(1);
- }else if(temp == son)
- {//儿子吃橘子
- if(!(sem_p(sem_id)))
- {//申请进入盘子吃橘子,申请不成功则休眠
- printf("this is son ------------------------------\n");
- printf("The nunber of apples = %d\n",dishs->apple);
- printf("The number of orang = %d \n",dishs->orang);
- if(dishs->total_num > 0 && dishs->orang > 0)
- {//如果盘子里没有苹果则等待爸爸放苹果
- dishs->total_num--;
- dishs->orang--;
- printf("The son eat a orange!\n");
- }else
- printf("The son have no orange to eat\n");
- sem_v(sem_id);//释放信号量
- sleep(1);
- }
- }else if(temp == daughter)
- {//女儿吃苹果
- if(!sem_p(sem_id))
- {//申请进入盘子吃苹果,申请不成功则休眠
- printf("This is daughter---------------------------------\n");
- printf("The nunber of apples = %d\n",dishs->apple);
- printf("The number of orang = %d \n",dishs->orang);
- if(dishs->total_num > 0 && dishs->apple > 0)
- {//如果盘子里没有橘子,则女儿等待妈妈放橘子
- dishs->total_num--;
- dishs->apple--;
- printf("The duaghter eat a apple!\n");
- }else
- printf("The duaghter have no apple to eat\n");
- sem_v(sem_id);//释放信号量
- sleep(1);
- }
- }
- return 0;
- }
复制代码 斥关系。 |
|