生产者消费者问题的C语言实现

9 篇文章 0 订阅

实验六 生产者/消费者问题实验

一、实验目的

掌握Linux下生产者/消费者问题算法的实现

 

二、实验原理

1.clone系统调用:

功能:创建一个轻进程或线程

用法:

intclone (int (*fn)(void *arg),void *stack,int flag,void *arg);

其中,

★fn是轻进程所执行的函数;stack是轻进程所使用的栈

★flag是CLONE_VM,CLONE_FS,CLONE_FILES,CLONE_SIGNAND,CLONE_PID的组合

★arg是调用过程的对应参数

clone的关键是flag的设定

☆CLONE_VM表示子进程共享父进程的内存

☆CLONE_FS表示子进程共享父进程的文件系统

☆CLONE_SIGNAND表示子进程共享父进程的消息处理机制

☆CLONE_PID指子进程继承父进程的id号

 

 

2.sem_wait和sem_post系统调用:

sem_wait(&s)和sem_post(&s)分别相当于信号灯的P操作和V操作。其中,s是类型为sem_t的信号灯。初始化函数sem_init(s,0,8)。

 

3.pthread_mutex_lock和pthread_mutex_unlock系统调用:

pthread_mutex_lock(&mutex)和pthread_rmutex_unlock(&mutex)分别用于加锁和解锁。参数为mutex定义的互斥锁。初始pthread_mutex_init(&mutex,NULL)。

 

三、实验内容

1. 阅读以下源码,使用系统调用clone()创建两个生产者线程和两个消费者线程。当该程序运行时,在系统中有两个生产者线程和两个消费者线程并发执行。观察至少三次以上的运行结果并分析原因;(编译命令:gcc –pthread  -o  pc.out  producerconsumer.c

#include "sched.h"

#include "pthread.h"

#include "stdio.h"

#include "stdlib.h"

#include "semaphore.h"

 

#define BUFFER_LEN 8 //定义缓冲区长度

void producer(void *args);

void consumer(void *args);

pthread_mutex_t mutex;

sem_t product;

sem_t warehouse;

 

char buffer[BUFFER_LEN][4];

int in,out; //产品进、出缓冲区指针

int tot=0; //缓冲区中的产品总数

 

main(int argc,char **argv){

 pthread_mutex_init(&mutex,NULL); //对互斥信号量进行初始化

 sem_init(&product,0,0);    //对标识产品个数的信号量进行初始化

 sem_init(&warehouse,0,BUFFER_LEN); //对标识缓冲区中空位置个数的信号量进行初始化

 in=0;

 out=0;

  inti0=0,i1=1;

  intclone_flag, retval;

 char *stack;

 clone_flag=CLONE_VM|CLONE_SIGHAND|CLONE_FS|CLONE_FILES;

  //创建两个生产者和两个消费者线程

stack=(char *)malloc(4096);

 retval=clone((void *)producer,&(stack[4095]),clone_flag,(void*)&i0);

 

 stack=(char *)malloc(4096);

 retval=clone((void *)consumer,&(stack[4095]),clone_flag,(void*)&i0);

 

 stack=(char *)malloc(4096);

 retval=clone((void *)producer,&(stack[4095]),clone_flag,(void*)&i1);

 

 stack=(char *)malloc(4096);

 retval=clone((void *)consumer,&(stack[4095]),clone_flag,(void*)&i1);

 

 exit(1);

 

}

 

void producer(void *args){

  intid=*((int *)args);

  inti;

 for(i=0;i<10;i++){

   sleep(i+1);

    sem_wait(&warehouse);

   pthread_mutex_lock(&mutex);

   if(id==0)

     strcpy(buffer[in],"aaa\0");

   else

     strcpy(buffer[in],"bbb\0");

   printf("producer %d produces %s in %d\n",id,buffer[in],in);

  

   in=(in+1)%BUFFER_LEN;

   tot++; //当前产品总数加1

   printf("*****the number of products:%d*****\n",tot);

   pthread_mutex_unlock(&mutex);

   sem_post(&product);

  }

 printf("producer %d is over!\n",id);

}

 

void consumer(void *args){

  intid=*((int *)args);

  inti;

 for(i=0;i<10;i++){

   sleep(10-i);

   sem_wait(&product);

   pthread_mutex_lock(&mutex);

   printf("consumer %d get %s in %d\n",id,buffer[out],out);

   out=(out+1)%BUFFER_LEN;

   tot--; //当前产品总数减1

   printf("*****the number of products:%d*****\n",tot);

   pthread_mutex_unlock(&mutex);

   sem_post(&warehouse);

  }

 printf("consumer %d is over!\n",id);

}

2. 修改上述代码,将producer函数中的sem_wait(&warehouse)和pthread_mutex_lock(&mutex)两行交换。观察至少三次以上的运行结果并分析原因;

3. 修改上述代码,将producer函数中的sem_wait(&warehouse)和pthread_mutex_lock(&mutex)两行交换,并且创建两个生产者线程和一个消费者线程。观察至少三次以上的运行结果并分析原因。

(注意:用linux中用ctrl+z返回到输入命令行方式)

 

四、实验要求

请同学们参考给出代码完成本次实验。

该实验为操作型实验,其实验报告书写要求如下:

n  实验原理:阐述系统调用的用法。

n  实验方案设计:利用clone系统调用实现线程创建、利用sem_wait和sem_post系统调用完成PV操作、利用pthread_mutex_lock和pthread_mutex_unlock实现进程互斥。

n  实验过程应包括:为给出的源程序加上注释

n  实验结论应包括:程序运行结果,粘贴上拷屏的图(注意:为jpg格式)

n  小结应包括:三段程序运行结果及原因分析、实验的体会及收获、对搞好今后实验提出的建设性建议。

提交内容:实验报告


  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值