linux了解信号量机制,了解并掌握进程同步和互斥机制
本帖最后由 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;
}
斥关系。
页:
[1]