- 论坛徽章:
- 0
|
用条件变量和锁进行线程控制,问题如注释所写。就是消费者线程内的那个usleep语句,为什么它那么重要
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
//多个生产者多个消费者
#define BUFFSIZ 100000
#define MAXTHREADS 10
struct
{
int value;
pthread_t tid;
} buf[BUFFSIZ];
struct
{
pthread_mutex_t mutex;
int index;//生产者使用,索引buf位置
} shared = { PTHREAD_MUTEX_INITIALIZER, 0};
struct
{
pthread_mutex_t mutex;
pthread_cond_t cond;
int ready;//在该索引及之前的元素可以消费
int consume;//消费者将要消费的元素下标
} nready = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, -1, 0};
void *produce(void *arg)
{
for (;;)
{
pthread_mutex_lock(&shared.mutex);
if (shared.index > BUFFSIZ - 1)
{
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);
usleep(1);
}
}
void *consume(void *arg)
{
int i;
for (;;)
{
pthread_mutex_lock(&nready.mutex);
if ( nready.consume>= BUFFSIZ)
{
pthread_mutex_unlock(&nready.mutex);
// printf("consume thread %lu is donen", pthread_self());
return NULL;
}
while ( nready.ready < nready.consume)
pthread_cond_wait(&nready.cond, &nready.mutex);
if ( buf[nready.consume].value != nready.consume)
printf("error: buf[%d]=%d, tid = %lun", nready.consume, buf[nready.consume].value, buf[nready.consume].tid);
++nready.consume;
pthread_mutex_unlock(&nready.mutex);
usleep(1);// 如果没有这句,多个消费者就会死锁。
++(*(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);
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 donen", tid_produce[i]);
}
for (i = 0; i < ncons; i++)
{
pthread_join(tid_consume[i], NULL);
printf("consume thread %lu is donen", 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);
}
|
|
|