起步于308的小菜菜

no money no dream coder 一枚

多线程之生产者于消费者问题

生产者线程向一缓冲区中写入数据~消费者线程从缓冲区中读取数据,由于生产者线程和消费者线程共享同一缓冲区,为了正确的读写数据,在使用缓冲队列时必须保持互至。生产者线程和消费者线程必须满足:生产者写入的缓冲区的数目不能超过缓冲区的容量,消费者线程读取的数目不能超过生产者写入的数目。初始化读写指针为0,如果读指针等于写指针。则缓冲区是空的~如果(写指针+1) % N 等于读指针,则缓冲区是满的 code

(proandcon.c) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>
#include<time.h>
#include<math.h>
#define BUFFER_SIZE 8

struct prodcons {
 int buffer[BUFFER_SIZE];
 pthread_mutex_t lock;
 int readpos,writepos;
 pthread_cond_t notempty;
 pthread_cond_t notfull;
};

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 ;
}

void put(struct prodcons *b,int data)
{
  pthread_mutex_lock(&b->lock);
  if((b->writepos + 1)%BUFFER_SIZE == b->readpos)
  {
    pthread_cond_wait(&b->notfull,&b->lock);
  }
  b->buffer[b->writepos] = data;
  b->writepos++;
 if(b->writepos >= BUFFER_SIZE)
     b->writepos = 0;
 pthread_cond_signal(&b->notempty);
 pthread_mutex_unlock(&b->lock);
}

int get(struct prodcons *b)
{
 int data;
 pthread_mutex_lock(&b->lock);
 if(b->writepos == b->readpos)
 {
  pthread_cond_wait(&b->notempty,&b->lock);
 }
 data = b->buffer[b->readpos];
 b->readpos++;

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

 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 < 50 ; n++)
 {
  printf("%d\t",n);
  put(&buffer,n);
 }
 put(&buffer,OVER);
 return NULL;
}
void *consumer(void *data)
{
  int d;
  while(1)
  {
   d = get(&buffer);
   if(d == OVER)
       break;
   printf("%d\t",d);
  }
  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);
  pthread_join(th_a,&retval);
  pthread_join(th_b,&retval);
  printf("\n");
  return 0;
}

Comments