资源简介
使用信号量实现有限缓冲区的生产者和消费者问题
使用信号量实现读进程具有优先权的读者和写者问题
实验报告(内容、环境、遇到的问题及解决、源代码、流程图、总结)
源代码
代码片段和文件信息
#include
#include
#include
#include
#include
#include
#include
#include
#define PRODUCER 1 //宏定义生产者个数, 2个
#define COSTOMER 12 //宏定义消费者个数, 3个
#define WRITE_NUM 12//宏定义写缓冲次数, 6次
#define READ_NUM 1 //宏定义读缓冲次数, 4次
#define SEM_ALL_KEY 1342
#define SEM_EMPTY 0
#define SEM_FULL 1
#define BUF_LENGTH (sizeof(struct container_buffer)) //宏定义缓冲区大小
#define BUFFER_NUM 4 //宏定义缓冲区个数 , 3个
#define SHM_MODE 0600 //宏定义创建和访问标志
//缓冲区结构(循环队列)
struct container_buffer //定义共享缓冲区结构
{
char letter[BUFFER_NUM];
int head;
int tail;
int is_empty; //判断缓冲区是否为空的标志
};
//得到6以内的一个随机数,产生延迟时间
int random_num()
{
int t;
srand((unsigned)(getpid() + time(NULL)));
t = rand() % 4;
return t;
}
//semWait操作,获得使用权
void semWait(int sem_id int sem_num)
{
struct sembuf sem_buff;
sem_buff.sem_num = sem_num;
sem_buff.sem_op = -1;
sem_buff.sem_flg = 0;
semop(sem_id &sem_buff 1);
}
//得到一个随机字符模拟产品名字
char random_letter()
{
char a;
srand((unsigned)(getpid() + time(NULL)));
a = (char)((char)(rand() % 26) + ‘a‘);
return a;
}
//semSignal操作,释放使用权
void semSignal(int sem_id int sem_num)
{
struct sembuf sem_buff;
sem_buff.sem_num = sem_num;
sem_buff.sem_op = 1;
sem_buff.sem_flg = 0;
semop(sem_id &sem_buff 1);
}
//主函数
int main(int argc char * argv[])
{
int shm_id sem_id; //定义共享内存段标识变量shm_id,定义信号量标识变量sem_id
int num_p = 0 num_c = 0 i j; //定义生产者和消费者的个数变量,初始化为0
struct container_buffer * shmptr; //指向缓冲区结构的指针
char pn; //随机字符,代表产品
pid_t pid_p pid_c; //进程pid变量
printf(“start...\n“);
sem_id = semget(SEM_ALL_KEY 2 IPC_CREAT | 0660); //创建两个信号量 empty full
semctl(sem_id SEM_EMPTY SETVAL BUFFER_NUM);
//索引为SEM_EMPTY的信号量值为3
semctl(sem_id SEM_FULL SETVAL 0);
//索引为SEM_FULL的信号量值为0
if ((shm_id = shmget(IPC_PRIVATE BUF_LENGTH SHM_MODE)) < 0)
//申请一个共享主存段大小为缓冲区大小
{
printf(“申请一个共享主存段失败\n“);
exit(1); //失败退出
}
if ((shmptr = shmat(shm_id 0 0)) == (void *)-1) //将共享段与进程相连
{
printf(“将共享段与本进程相连失败\n“);
exit(1); //失败退出
}
shmptr->head = 0; //初始化缓冲区
shmptr->tail = 0;
shmptr->is_empty = 1;
for(;num_p {
if ((pid_p = fork()) < 0) //创建一个进程
{
printf(“创建子进程失败\n“);
exit(1); //失败退出
}
//如果是子进程,开始创建生产者
if (pid_p == 0)
{
if ((shmptr = shmat(shm_id 0 0)) == (void *)-1) //将共享段与本进程相连
{
printf(“将共享段与本进程相连失败\n“);
exit(1); //失败退出
}
for (i = 0; i < WRITE_NUM; i++) //循环尝试在缓冲区内放入数据为WRITE_NUM次
{
semWait(sem_id SEM_EMPTY); //semWait操作,申请使用权semWait(empty)
sleep(random_num()); //随机等待一段时间
shmptr->letter[shmptr->tail] = pn = random_letter();
//在缓冲队列里面放入一个产品
shmptr->tail = (shmptr->tail + 1) % BUFFER_NUM;
shmptr->is_empty = 0;
//更新缓冲区状态为满
printf(“生产者%d生产产品%c\t当前缓冲区为: “num_p pn); //输出动作序列
for (j = (shmptr->tail - 1 >= shmptr->head) ?(shmptr->tail - 1) : (shmptr->tail - 1 + BUFFER_NUM); !(shmptr->is_empty)&& j >= shmptr->head; j--)
//输出缓冲区状态
{
printf(“%c“ shmptr->letter
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 5776 2017-12-24 17:41 producer_consumer.c
文件 538674 2017-12-24 17:22 实验报告.docx
文件 2711 2017-12-24 17:40 reader_writer.c
- 上一篇:2017年下半年 网络工程师 答案详解
- 下一篇:基于深度学习的神经网络算法论文
评论
共有 条评论