📄 tx.c
字号:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<linux/shm.h>
#include<linux/sem.h>
// #define BUFSIZE 10 //定义缓冲区大小
int empty,full,mutex; //定义内存空、满、互斥三个信号量
int producer,customerA,customerB; //声明生产者消费者
int shmid1,shmid2,i; //定义共享存储区的描述符
int set=0; //缓冲区号的计数
int main()
{
int *array,*get; //虚拟地址空间
struct sembuf P,V; //定义P、V操作所用的数据结构
union semun arg; //定义给信号量赋初值的参数数据结构
shmid1=shmget(IPC_PRIVATE,5,0666|IPC_CREAT); //创建一共享内存
shmid2=shmget(IPC_PRIVATE,1,0666|IPC_CREAT); //创建第二个共享内存
array=(int*)shmat(shmid1,0,0); //附接到共享内存上(数值型)
get=(int*)shmat(shmid2,0,0);
empty=semget(IPC_PRIVATE,1,0666|IPC_CREAT); //创建一个新的信号量empty
arg.val=5; //为空信号量赋值5
semctl(empty,0,SETVAL,arg);
full=semget(IPC_PRIVATE,1,0666|IPC_CREAT);
arg.val=0; //为满信号量赋值0
semctl(full,0,SETVAL,arg);
mutex=semget(IPC_PRIVATE,1,0666|IPC_CREAT);
arg.val=1; //设置互斥信号量1
semctl(mutex,0,SETVAL,arg);
/*定义信号量的P操作*/
P.sem_num=0; //第一个信号量
P.sem_op=-1; //负数:则相当于P操作
P.sem_flg=SEM_UNDO; //指明内核为信号量操作保留恢复值
/*定义信号量的V操作*/
V.sem_num=0;
V.sem_op=1; //正数:此时相当于V操作
V.sem_flg=SEM_UNDO;
while((producer=fork())==-1); //利用fork()函数创建生产者子进程
if(producer==0)
{
for(i=0;i<10;i++)
{
semop(empty,&P,1); //判断共享区空否
semop(mutex,&P,1); //进入临界区前执行P操作(使用方法同P课上讲解的操作)
printf("producer inputs data:%d\n",i);
array[set]=i;
set++; //计数
sleep(1);
semop(mutex,&V,1); //出临界区执行V操作(使用方法同V课上讲解的操作)
semop(full,&V,1);
}
exit(0); //生产者子进程终止
}
else{
while((customerA=fork())==-1);//创建消费者A进程
if(customerA==0)
{
for(i=0;i<10;i++)
{
sleep(1);
semop(full,&P,1); //判断共享区满否
semop(mutex,&P,1);//进入临界区前执行P互斥操作(使用方法同P课上讲解的操作)
printf("customerA:%d\n",array[*get]);
(*get)++;
sleep(1);
semop(mutex,&V,1);
semop(empty,&V,1);
}
exit(0); //消费者A子进程终止
}
else{
while((customerB=fork())==-1);//创建消费者B进程
if(customerB==0)
{
for(i=0;i<10;i++)
{
sleep(1);
semop(full,&P,1);
semop(mutex,&P,1);
printf("customerB:%d\n",array[*get]);
(*get)++;
sleep(1);
semop(mutex,&V,1);
semop(empty,&V,1);
}
exit(0); //消费者B子进程终止
}
else{
wait(0); //等待子进程结束
wait(0);
wait(0);
shmdt(array); //将共享内存从进程的地址空间1断开
shmctl(shmid1,IPC_RMID,0);//撤消共享存储区
shmdt(get); //将共享内存从进程的地址空间2断开
shmctl(shmid2,IPC_RMID,0);
/*撤消三个信号量*/
semctl(empty,IPC_RMID,0);
semctl(full,IPC_RMID,0);
semctl(mutex,IPC_RMID,0);
exit(0);
}
}
}
}
student@saturn1:~$ gcc -o 2 2.c
student@saturn1:~$ ./2
producer inputs data:0
producer inputs data:1
customerA:0
producer inputs data:2
student@saturn1:~$ ./
bash: ./: is a directory
student@saturn1:~$ ./2
producer inputs data:0
producer inputs data:1
customerA:0
producer inputs data:2
customerB:1
producer inputs data:3
customerA:2
producer inputs data:4
customerB:3
producer inputs data:5
customerA:4
producer inputs data:6
customerB:5
producer inputs data:7
customerA:6
producer inputs data:8
customerB:7
producer inputs data:9
customerA:8
customerB:9
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -