专栏中心

EEPW首页 > 专栏 > Linux多线程信号量的问题

Linux多线程信号量的问题

发布人:hikesoso2010 时间:2011-03-08 来源:工程师 发布文章

  有一个有限缓冲区和两个线程:生产者和消费者。他们分别把产品放入缓冲区和从缓冲区中拿走产品。当一个生产者在缓冲区满时必须等待,当一个消费者在缓冲区空时也必须等待:

  (1)信号量的考虑

  这里使用3个信号量,其中两个信号量avail和full分别用于解决生产者和消费者线程之间的同步问题,mutex是用于这两个线程之间的互斥问题。其中avail初始化N(有界缓冲区的空单元数),mutex初始化为1,full初始化为0。

  #include <stdio.h>

  #include <stdlib.h>

  #include <unistd.h>

  #include <pthread.h>

  #include <errno.h>

  #include <sys/ipc.h>

  #include <semaphore.h>

  #include <fcntl.h>

  #include <string.h>

  #define FIFO "myfifo"

  #define N 5

  int lock_var;

  time_t end_time;

  char buf_r[100];

  sem_t mutex,full,avail;

  int fd;

  void pthread1(void *arg);

  void pthread2(void *arg);

  void productor(void *arg);

  void consumer(void *arg);

  int main(int argc,char *argv[])

  {

  pthread_t id1,id2;

  pthread_t mon_th_id;

  int ret;

  end_time = time(NULL) + 30;

  /*创建有名管道*/

  if((mkfifo(FIFO,O_CREAT|O_EXCL)<0) && (errno!=EEXIST))

  printf("cannot create fifoserver\n");

  printf("Preparing for reading bytes...\n");

  memset(buf_r,0,sizeof(buf_r));

  /*打开管道*/

  fd = open(FIFO,O_RDWR | O_NONBLOCK,0);

  if(fd==-1)

  {

  perror("open error!\n");

  exit(1);

  }

  /*初始化互斥信号量 1*/

  ret = sem_init(&mutex,0,3);

  /*初始化avail信号量为N*/

  ret = sem_init(&avail,0,N);

  /*初始化full信号量为0*/

  ret = sem_init(&full,0,0);

  if(ret!=0)

  {

  perror("sem_init error \n");

  }

  /*创建两个线程*/

  /* ret = pthread_create(&id2,NULL,(void *)consumer,NULL);

  if(ret !=0)

  perror("pthread create 2\n");*/

  printf("mid pthread\n");

  ret = pthread_create(&id1,NULL,(void *)productor,NULL);

  if(ret!=0)

  perror("pthread create 1\n");

  ret = pthread_create(&id2,NULL,(void *)consumer,NULL);

  if(ret !=0)

  perror("pthread create 2\n");

  pthread_join(id1,NULL);

  pthread_join(id2,NULL);

  exit(0);

  }

  /*生产者线程*/

  void productor(void *arg)

  {

  int i,nwrite;

  while(time(NULL)<end_time)

  {

  /* P 操作信号量avail和mutex*/

  sem_wait(&avail);

  sem_wait(&mutex);

  /*生产者写入数据*/

  if((nwrite=write(fd,"hello",5))==-1)

  {

  if(errno==EAGAIN)

  printf("The FIFO has not been read yet.Please try later\n");

  }

  else

  printf("write hello to the FIFO\n");

  /*V操作信号量full和mutex*/

  sem_post(&full);

  sem_post(&mutex);

  sleep(1);

  }

  }

  /*消费者线程*/

  void consumer(void *arg)

  {

  int nolock = 0;

  int ret,nread;

  while(time(NULL)<end_time)

  {

  /*P操作信号量full和mutex*/

  sem_wait(&full);

  sem_wait(&mutex);

  memset(buf_r,0,sizeof(buf_r));

  if((nread=read(fd,buf_r,100))==1)

  {

  if(errno==EAGAIN)

  printf("no data yet\n");

  }

  printf("read %s from FIFO\n",buf_r);

  sem_post(&avail);

  sem_post(&mutex);

  sleep(1);

  }

  }

         96堆栈 软件编程网http://www.96dz.com,提供C语言、C++编程、VC++编程、Java编程、C#编程、NET编程、Linux编程、Web编程等全面技术信息,编程开发教程、视频教程、培训教程及相关资料的下载。

专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们

关键词:

相关推荐

安控 Rock E20系列PLC模块使用手册

字里行间:3D NAND闪存的下一个前沿

网络与存储 2025-12-01

安控 RockE20系列PLC EMC使用手册

Tektronix 公司产品梗概

视频 2009-07-20

NVMe时代的RAID

今昔对比:磁芯

网络与存储 2025-12-01

寻找5.5G和6G过程控制采用的路径

保护的差异:以太网供电与数据线供电

高性能计算不仅仅是搭乘人工智能的顺风车

台积电将在中国台湾建设十座2纳米晶圆厂

EDA/PCB 2025-12-01

串口精灵

资源下载 2007-02-09

英伟达对谷歌回归人工智能感到非常害怕

如何精确的使用示波器进行测量!

视频 2009-07-20

学习并行总线波形捕获与分析!

NVIDIA、苹果争抢台积电产能 分别卡位A16、A14制程

EDA/PCB 2025-12-01

DC-DC 转换器工作原理是什么?

视频 2009-07-24

钻石传感器测量纳米级磁性

富士N系列PLC编程软件

资源下载 2007-02-09
更多 培训课堂
更多 焦点
更多 视频

技术专区