看到别人写的,可是不是我想要的形式,改写下。
先运行消费者进程
producer.c
#include<sys/types.h>
#include<sys/sem.h>#include<sys/shm.h>
#include<sys/ipc.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<time.h>
#include <stdlib.h>
#include <string.h>
#ifndef _SEMUN_H
#define _SEMUN_H
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short int *array; /* array for GETALL, SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
#endif
#define MAXSHM 5 //定义缓冲区数组的下标变量个数
/* 定义3个信号量的内部标识 */
struct node{
int array[MAXSHM];
int fullid;
int emptyid;
int mutexid;
int get;
}* pshare;
/* 主函数 */
int main()
{
/* 定义共享内存的ID */
int shid;
/* 创建共享内存 */
shid = shmget(1024, sizeof(struct node), 0666);
/* 初始化共享内存 */
pshare = (struct node *) shmat(shid, 0, 0);
/* 定义信号量数据结构 */
struct sembuf P, V;
union semun arg;
/* 初始化 P V操作 */
P.sem_num = 0;
P.sem_op = -1;
P.sem_flg = SEM_UNDO;
V.sem_num = 0;
V.sem_op = 1;
V.sem_flg = SEM_UNDO;
/* 生产者进程 */
int i = 0;
int set = 0;
while (i < 10)
{
semop(pshare->emptyid, &P, 1); //对 emptyid执行P操作
semop(pshare->mutexid, &P, 1); //对 mutexid执行 P操作
pshare->array[set % MAXSHM] = i;
printf("Producer put number %d to No.%d\n",pshare->array[set%MAXSHM],set%MAXSHM);
set++; //写计数加1
semop(pshare->mutexid, &V, 1); //对mutexid执行 V 操作
semop(pshare->fullid, &V, 1); //对fullid执行 V 操作
i++;
}
sleep(3); //SLEEP 3秒,等待消费者进程执行完毕
printf("Poducer if over\n");
exit(0);
}
consumer.c
#include<sys/types.h>
#include<sys/sem.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<time.h>
#include <stdlib.h>
#include <string.h>
#ifndef _SEMUN_H
#define _SEMUN_H
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short int *array; /* array for GETALL, SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
#endif
#define MAXSHM 5 //定义缓冲区数组的下标变量个数
/* 定义3个信号量的内部标识 */
struct node{
int array[MAXSHM];
int fullid;
int emptyid;
int mutexid;
int get;
}* pshare;
/* 主函数 */
int main()
{
/* 定义共享内存的ID */
int shid;
/* 创建共享内存 */
shid = shmget(1024, sizeof(struct node), IPC_CREAT | 0666);
/* 初始化共享内存 */
pshare = (struct node *) shmat(shid, 0, 0);
memset(pshare,0,sizeof(struct node));
/* 定义信号量数据结构 */
struct sembuf P, V;
union semun arg;
/* 创建信号量 */
pshare->fullid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
pshare->emptyid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
pshare->mutexid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
/*初始化信号量 */
arg.val = 0; //初始时缓冲区中无数据
if(semctl(pshare->fullid,0,SETVAL,arg)==-1)
perror("semctl setval error");
arg.val = MAXSHM; //初始时缓冲区中有5个空闲的数组元素
if(semctl(pshare->emptyid,0,SETVAL,arg)==-1)
perror("semctl setval error");
arg.val = 1; //初始时互斥信号为1,允许一个进程进入
if(semctl(pshare->mutexid,0,SETVAL,arg)==-1)
perror("semctl setval error");
/* 初始化 P V操作 */
P.sem_num = 0;
P.sem_op = -1;
P.sem_flg = SEM_UNDO;
V.sem_num = 0;
V.sem_op = 1;
V.sem_flg = SEM_UNDO;
/* 消费者A进程 */
if(fork()==0)
{
printf("ConsunerA is begin\n");
while(1)
{
if(pshare->get==10)
break;
printf("in a\n");
semop(pshare->fullid,&P,1); //对fullid执行 P 操作
semop(pshare->mutexid,&P,1);//对mutexid执行 P 操作
printf("The ConsumerA get number %d from No.%d\n",pshare->array[pshare->get%MAXSHM],(pshare->get)%MAXSHM);
(pshare->get)++;//读计数加1
semop(pshare->mutexid,&V,1);//对mutexid执行 V 操作
semop(pshare->emptyid,&V,1);//对fullid执行 V 操作
sleep(1);
}
printf("ConsunerA is over\n");
exit(0);
}
else
{
/*消费者B进程 */
if(fork()==0)
{
printf("ConsunerB is begin\n");
while(1)
{
if(pshare->get==10)
break;
printf("in b\n");
semop(pshare->fullid,&P,1); //对fullid执行 P 操作
semop(pshare->mutexid,&P,1);//对mutexid执行 P 操作
printf("The ConsumerB get number %d from No.%d\n",pshare->array[pshare->get%MAXSHM],(pshare->get)%MAXSHM);
(pshare->get)++;//读计数加1
semop(pshare->mutexid,&V,1);//对mutexid执行 V 操作
semop(pshare->emptyid,&V,1);//对emptyid执行 V 操作
sleep(1);
}
printf("ConsunerB is over\n");
exit(0);
}
}
/* 父进程返回后回收3个子进程 */
wait(0);
wait(0);
/* 撤消3个信号量集 */
semctl(pshare->emptyid, IPC_RMID, 0);
semctl(pshare->fullid, IPC_RMID, 0);
semctl(pshare->mutexid, IPC_RMID, 0);
/* 断开并撤消2个共享内存 */
shmdt(pshare);
shmctl(shid, IPC_RMID, 0);
exit(0);
}