生产者代码:
/*
* 生产者消费者模型
* 生产者代码实现
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SHM_SIZE 10 //共享内存大小
void pro_exit(char str[], int temp) //程序出错,打印错误信息并退出程序
{
if(temp == -1)
{
perror(str);
exit(0);
}
}
int main(void)
{
int sem_id, //保存信号量ID
shm_id; //保存共享内存ID
key_t sem_key, //保存信号量关键值
shm_key; //保存共享内存关键值
struct sembuf lock0 = {0, -1, 0}; //互拆锁上锁
struct sembuf unlock0 = {0, 1, 0}; //互拆锁解锁
struct sembuf lock1 = {1, -1, 0};
struct sembuf unlock1 = {1, 1, 0};
struct sembuf lock2 = {2, -1, 0};
struct sembuf unlock2 = {2, 1, 0};
int *p; //指向共享内存
int ret;
int n = 100;
sem_key = ftok("lzy", 2); //获取互斥锁关键值
pro_exit("sem_ftok", sem_key); //检测程序是否出错
if((sem_id = semget(sem_key, 3, IPC_CREAT |IPC_EXCL | 0666)) < 0) //创建三个信号量互斥锁
{
sem_id = semget(sem_key, 0, 0); //读取已存在的互斥锁
pro_exit("semget", sem_id);
}
else
{
ret = semctl(sem_id, 0, SETVAL, 1); //设置互斥锁的值为1
pro_exit("semctl_0", ret);
ret = semctl(sem_id, 1, SETVAL, 10); //设置生产者允许生产最大值为30
pro_exit("semctl_1", ret);
ret = semctl(sem_id, 2, SETVAL, 0); //设置消费者允许最小消费
pro_exit("semctl_2", ret);
}
shm_key = ftok("lzy", 1); //获取共享内存关键值
pro_exit("shm_ftok", shm_key); //检测程序是否出错
shm_id = shmget(shm_key, SHM_SIZE, IPC_CREAT | 0666); //创建共享内存
pro_exit("shmget", shm_id);
p = (int *)shmat(shm_id, NULL, 0); //映像共享内存
pro_exit("shmat", (int)*p);
while(n--)
{
semop(sem_id, &lock1, 1); //生产者上锁
ret = semop(sem_id, &lock0, 1); //互斥锁上锁
pro_exit("semop_lock", ret);
(*p)++;
printf("process %d : count = %d\n", getpid(),*p); //加一
ret = semop(sem_id, &unlock0, 1); //互斥锁解锁
pro_exit("semop_unlock", ret);
semop(sem_id, &unlock2, 1); //消费者加一
sleep(1);
}
ret = shmdt(p); //释放共享内存
pro_exit("shmdt", ret);
ret = shmctl(shm_id, IPC_RMID, NULL); //删除共享内存
pro_exit("shmctl", ret);
ret = semctl(sem_id, 0, IPC_RMID); //删除信号量
pro_exit("semctl", ret);
return 0;
}
消费者代码:
/*
* 生产者消费者模型
* 消费者代码实现
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SHM_SIZE 10 //共享内存大小
void pro_exit(char str[], int temp) //程序出错,打印错误信息并退出程序
{
if(temp == -1)
{
perror(str);
exit(0);
}
}
int main(void)
{
int sem_id, //保存信号量ID
shm_id; //保存共享内存ID
key_t sem_key, //保存信号量关键值
shm_key; //保存共享内存关键值
struct sembuf lock0 = {0, -1, 0}; //互拆锁上锁
struct sembuf unlock0 = {0, 1, 0}; //互拆锁解锁
struct sembuf lock1 = {1, -1, 0};
struct sembuf unlock1 = {1, 1, 0};
struct sembuf lock2 = {2, -1, 0};
struct sembuf unlock2 = {2, 1, 0};
int *p; //指向共享内存
int ret;
int n = 100;
sem_key = ftok("lzy", 2); //获取互斥锁关键值
pro_exit("sem_ftok", sem_key); //检测程序是否出错
if((sem_id = semget(sem_key, 3, IPC_CREAT |IPC_EXCL | 0666)) < 0) //创建三个信号量互斥锁
{
sem_id = semget(sem_key, 0, 0); //读取已存在的互斥锁
pro_exit("semget", sem_id);
}
else
{
ret = semctl(sem_id, 0, SETVAL, 1); //设置互斥锁的值为1
pro_exit("semctl_0", ret);
ret = semctl(sem_id, 1, SETVAL, 10); //设置生产者允许生产最大值为30
pro_exit("semctl_1", ret);
ret = semctl(sem_id, 2, SETVAL, 0); //设置消费者允许最小消费
pro_exit("semctl_2", ret);
}
shm_key = ftok("lzy", 1); //获取共享内存关键值
pro_exit("shm_ftok", shm_key); //检测程序是否出错
shm_id = shmget(shm_key, SHM_SIZE, IPC_CREAT | 0666); //创建共享内存
pro_exit("shmget", shm_id);
p = (int *)shmat(shm_id, NULL, 0); //映像共享内存
pro_exit("shmat", (int)*p);
while(n--)
{
semop(sem_id, &lock2, 1); //消费者上锁
ret = semop(sem_id, &lock0, 1); //互斥锁上锁
pro_exit("semop_lock", ret);
(*p)--;
printf("ser %d : count = %d\n", getpid(),*p); //一
ret = semop(sem_id, &unlock0, 1); //互斥锁解锁
pro_exit("semop_unlock", ret);
semop(sem_id, &unlock1, 1); //生产者加一
sleep(1);
}
ret = shmdt(p); //释放共享内存
pro_exit("shmdt", ret);
ret = shmctl(shm_id, IPC_RMID, NULL); //删除共享内存
pro_exit("shmctl", ret);
ret = semctl(sem_id, 0, IPC_RMID); //删除信号量
pro_exit("semctl", ret);
return 0;
}