一个很好的多线程和互斥锁学习例程,是一个生产者-消费者的模型
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#define BUFFER_SIZE 16
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);//获取互斥锁
while((b->writepos + 1) % BUFFER_SIZE == b->readpos)
{
printf("wait for not full\n");
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);
while(b->writepos == b->readpos)
{
printf("wait for not empty\n");
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<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);
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
return 0;
}
pthread_cond_wait函数,是线程阻塞在一个条件变量上,原型为:
extern int pthread_cond_wait(pthread_cond_t *_restrict_cond, pthread_mutex_t* _restrict_mutex)
线程解开mutex指向的锁并被条件变量cond阻塞,线程可以被函数pthread_cond_signal和pthread_cond_broadcast唤醒。
还有另一个函数pthread_cond_timedwait函数,他比vpthread_cond_wait函数多一个时间参数,经历给定时间後,阻塞将被解除。