一個很好的多線程和互斥鎖學習例程,是一個生產者-消費者的模型
#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函數多一個時間參數,經歷給定時間後,阻塞將被解除。