64,644
社区成员
发帖
与我相关
我的任务
分享
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 50000
#define MAXTHREADS 10
struct
{
int value;
pthread_t tid;
} buf[SIZE];
struct
{
pthread_mutex_t mutex;
int index;//生产者使用,索引buf位置
} shared = { PTHREAD_MUTEX_INITIALIZER, 0};
struct
{
pthread_mutex_t mutex;
pthread_cond_t cond;
// int num; // num of elems to be consumed, by p-c
// int consumed;// num of elems already be read, only by consumer
int ready;//在该索引及之前的元素可以消费
int consume;//消费者将要消费的元素下标
} nready = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, -1, 0};
void *produce(void *arg)
{
for (;;)
{
usleep(1);
pthread_mutex_lock(&shared.mutex);
if (shared.index == SIZE )
{
pthread_mutex_unlock(&shared.mutex);
return NULL;
}
buf[shared.index].value = shared.index;
buf[shared.index].tid = pthread_self();
++shared.index;
pthread_mutex_unlock(&shared.mutex);
pthread_mutex_lock(&nready.mutex);
++nready.ready;
if ( nready.ready == nready.consume)
pthread_cond_broadcast(&nready.cond);
pthread_mutex_unlock(&nready.mutex);
++(*(int *)arg);
}
}
void *consume(void *arg)
{
for (;;)
{
usleep(1);
pthread_mutex_lock(&nready.mutex);
if ( nready.consume == SIZE )
{
if (nready.ready != SIZE - 1)
{
exit(3);//error
}
pthread_mutex_unlock(&nready.mutex);
return NULL;
}
while ( nready.consume < SIZE && nready.ready < nready.consume )
pthread_cond_wait(&nready.cond, &nready.mutex);
if (nready.consume == SIZE)
{
pthread_mutex_unlock(&nready.mutex);
return NULL;
}
if ( buf[nready.consume].value != nready.consume)
printf("error: buf[%d]=%d, tid = %lu\n", nready.consume, buf[nready.consume].value, buf[nready.consume].tid);
++nready.consume;
pthread_mutex_unlock(&nready.mutex);
++(*(int *)arg);
}
}
int main(int argc, char *argv[])
{
int i, nprod, ncons ;
pthread_t tid_produce[MAXTHREADS], tid_consume[MAXTHREADS];
int pcount[MAXTHREADS] = {0};
int ccount[MAXTHREADS] = {0};
if (argc != 3)
perror("usage: a.out <#producer线程数> <#consumer线程数>"), exit(1);
nprod = atoi(argv[1])> MAXTHREADS ? MAXTHREADS : atoi(argv[1]);
ncons = atoi(argv[2])> MAXTHREADS ? MAXTHREADS : atoi(argv[2]);
pthread_setconcurrency(nprod+ncons+1);
for (i = 0; i < nprod; i++)
pthread_create(&tid_produce[i], NULL, produce, &pcount[i]);
for (i = 0; i < ncons; i++)
pthread_create(&tid_consume[i], NULL, consume, &ccount[i]);
for (i = 0; i < nprod; i++)
{
pthread_join(tid_produce[i], NULL);
printf("produce thread %lu is done\n", tid_produce[i]);
}
for (i = 0; i < ncons; i++)
{
pthread_join(tid_consume[i], NULL);
printf("consume thread %lu is done\n", tid_consume[i]);
}
for(i=0; i<nprod; ++i)
printf(" producer %d \n", pcount[i]);
for(i=0; i<ncons; ++i)
printf(" consumer %d \n", ccount[i]);
exit(0);
}