请高手帮忙解释下这多线程的源代码,每句注释下 #include <stdio.h> #include <stdlib.h>

#include<time.h>#include"pthread.h"#defineBUFFER_SIZE16/*Circularbufferofintegers.*/s... #include <time.h>
#include "pthread.h"

#define BUFFER_SIZE 16

/* Circular buffer of integers. */
struct prodcons {
int buffer[BUFFER_SIZE]; /* the actual data */
pthread_mutex_t lock; /* mutex ensuring exclusive access to buffer */
int readpos, writepos; /* positions for reading and writing */
pthread_cond_t notempty; /* signaled when buffer is not empty */
pthread_cond_t notfull; /* signaled when buffer is not full */
};

/*--------------------------------------------------------*/
/* Initialize a buffer */
void init(struct prodcons * b)
{
pthread_mutex_init(&b->lock, NULL);
pthread_cond_init(&b->notempty, NULL);
pthread_cond_init(&b->notfull, NULL);
b->readpos = 0;
b->writepos = 0;
}
/*--------------------------------------------------------*/
/* Store an integer in the buffer */
void put(struct prodcons * b, int data)
{
pthread_mutex_lock(&b->lock);

/* Wait until buffer is not full */
while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) {
printf("wait for not full\n");
pthread_cond_wait(&b->notfull, &b->lock);
}
/* Write the data and advance write pointer */
b->buffer[b->writepos] = data;
b->writepos++;
if (b->writepos >= BUFFER_SIZE) b->writepos = 0;
/* Signal that the buffer is now not empty */
pthread_cond_signal(&b->notempty);

pthread_mutex_unlock(&b->lock);
}
/*--------------------------------------------------------*/
/* Read and remove an integer from the buffer */
int get(struct prodcons * b)
{
int data;
pthread_mutex_lock(&b->lock);

/* Wait until buffer is not empty */
while (b->writepos == b->readpos) {
printf("wait for not empty\n");
pthread_cond_wait(&b->notempty, &b->lock);
}
/* Read the data and advance read pointer */
data = b->buffer[b->readpos];
b->readpos++;
if (b->readpos >= BUFFER_SIZE) b->readpos = 0;
/* Signal that the buffer is now not full */
pthread_cond_signal(&b->notfull);

pthread_mutex_unlock(&b->lock);
return data;
}
#define OVER (-1)
struct prodcons buffer;
void * producer(void * data)
{ int n;
for (n = 0; n < 1000; n++) { printf(" put-->%d\n", n);
put(&buffer, n);
}
put(&buffer, OVER);
printf("producer stopped!\n");
return NULL;
}
void * consumer(void * data)
{
int d;
while (1)
{
d = get(&buffer);
if (d == OVER ) break;
printf(" %d-->get\n", d);
}
printf("consumer stopped!\n");
return NULL;
}
int main(void)
{ pthread_t th_a, th_b;
void * retval;
init(&buffer);
pthread_create(&th_a, NULL, producer, 0);
pthread_create(&th_b, NULL, consumer, 0);
/* Wait until producer and consumer finish. */
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
return 0;
}
展开
 我来答
dandanfeng166
推荐于2016-11-07 · TA获得超过779个赞
知道小有建树答主
回答量:196
采纳率:37%
帮助的人:85万
展开全部

首先这是一个生产者和消费者问题。

生产者producer负责产生数据,然后通过put操作将数据放到缓冲区buf中。

消费者consumer负责显示数据,通过get操作从缓冲区buf中读取数据。

========》

先看主函数main(),

生产者和消费者分别用两个线程来实现。

主函数中的pthread_create()函数就是用来创建这两个线程的。

开始定义了两个变量th_a,th_b用来记录这两个线程的线程号。

线程的程序体分别是producer,consumer。

接下来的pthread_join用来等待两个线程结束。因为如果不等待,main函数的主线程会立即结束,而两个子线程还来不及完全执行。

=======》

下面来分别看producer,consumer这两个线程。

producer循环一百次,每次调用put往buffer中放数据,最后放一个OVER;

consumer循环用get从buffer中读到数据并打印,直到读取的数据位OVER数据时结束。

=======》

我们再分别来看put操作和get操作。

由于put和get都要访问buf,buf就是一个临界资源,为了解决这个临界资源,在使用buf之前,要对它加锁。

pthread_mutex_lock(b->lock)一个为信号量加锁的函数。每个信号量只能加锁一次(我说的可能不准确),如果执行该函数的时候,参数中的信号量已经被加锁,则该函数阻塞,直到信号量被解锁才继续执行。这样就能保证信号量所保护的临界资源能够被互斥的访问。

struct prodcons { 

  int buffer[BUFFER_SIZE];      /* 这个就是循环缓冲区*/ 

  pthread_mutex_t lock;         /*这个是信号量,用来保证对缓冲区的互斥访问*/ 

  int readpos, writepos;        /* 这两个成员分别表示读位置和写位置*/ 

  pthread_cond_t notempty;      /* 这是表示缓冲区“非空”的条件信号量*/ 

  pthread_cond_t notfull;       /* 这是表示缓冲区“非满”的条件信号量*/ 

}; 

buf是一个循环的缓冲区,我们先来看缓冲区为空和满这两种状态时,读、写标记(readpos,writepos)的位置。

缓冲区为空时,readpos 和writepos指在同一位置;

换从去为满时,writepos位置的下一个位置就是readpos。 

/* put负责把数据放到缓冲区*/ 

void put(struct prodcons * b, int data) 

 //首先对互斥信号量进行加锁

 pthread_mutex_lock(&b->lock); 

 

   /* 这里就是判断缓冲区有没有满,用writepos+1与readpos比较,可以参考附图。

    * 因为是循环缓冲区,所以要模BUFFER_SIZE 。

    * 如果缓冲区满,将在while中等待,直到缓冲区非满,再继续执行。

    */ 

  while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) { 

  printf("wait for not full\n"); 

     //如果已经满了,则等待消费者读取了数据后发出“非满”信号。

     pthread_cond_wait(&b->notfull, &b->lock); 

   } 

  /* 当缓冲区非满时,将数据写入缓冲区中writepos对应的位置*/ 

   b->buffer[b->writepos] = data; 

  //更新writepos到下一个位置

   b->writepos++; 

  //循环利用缓冲区空间,如果超过了最大值,则从头开始。

   if (b->writepos >= BUFFER_SIZE) b->writepos = 0; 

  /* 向消费者发送信号,告诉消费者缓冲取非空 */ 

   pthread_cond_signal(&b->notempty); 

 

//对互斥信号进行解锁。

 pthread_mutex_unlock(&b->lock); 

/*--------------------------------------------------------*/ 

/* get负责从缓冲区中读取数据 */ 

int get(struct prodcons * b) 

   int data; 

//对互斥信号量进行加锁

 pthread_mutex_lock(&b->lock); 

 

  /* 判断缓冲区是否为空,为空则等待*/ 

   while (b->writepos == b->readpos) { 

     printf("wait for not empty\n"); 

  pthread_cond_wait(&b->notempty, &b->lock); 

   } 

   /* 读取readpos位置的数据 */ 

   data = b->buffer[b->readpos]; 

//更新readpos到下一个位置。

   b->readpos++; 

//循环利用缓冲区,回拨指针

   if (b->readpos >= BUFFER_SIZE) b->readpos = 0; 

   /* 发信号给生产者,缓冲区非满,可以放数据了*/ 

   pthread_cond_signal(&b->notfull); 

 

//对互斥信号量进行解锁

   pthread_mutex_unlock(&b->lock); 

   return data; 

}

昆酌空1512
2011-10-11
知道答主
回答量:56
采纳率:0%
帮助的人:65.9万
展开全部
1111111111111111
追问
老兄,你这回答有点混吧?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式