最近实习学习了点多线程的课程,老师让写个多线程的应用,本来自己想码一个银行排队请求服务的问题,奈何调试了下无果,贴下这个用条件变量实现的多线程问题吧。
用到的条件变量的函数:
条件变量数据结构: pthread_cond_t
初始化条件变量: pthread_con_init(pthread_cond_t *)
阻塞等待条件变量: pthread_con_wait
通知等待该条件变量的第一个线程: pthread_cond_sigal
通知等待该条件变量的所有线程: pthread_cond_broadcast
销毁条件变量状态: pthread_cond_destroy
the result screenshot
下面贴下书中码的代码:
/*
* =====================================================================================
*
* Filename: pthread_cond_exmaple.c
*
* Description: the product and the consumer
*
* Version: 1.0
* Created: 03/30/2014 06:47:52 PM
* Revision: none
* Compiler: gcc
*
* Author: wyl (), 1510178628@qq.com
* Organization:
*
* =====================================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#define BUFFER_SIZE 2
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* prod)
{
pthread_mutex_init(&prod->lock, NULL);
pthread_cond_init(&prod->notempty, NULL);
pthread_cond_init(&prod->notfull, NULL);
prod->readpos = 0;
prod->writepos = 0;
}
void put(struct prodcons* prod, int data)
{
pthread_mutex_lock(&prod->lock);
while((prod->writepos+1) % BUFFER_SIZE == prod->readpos)
{
printf("producter wait for not full\n");
pthread_cond_wait(&prod->notfull, &prod->lock);
}
prod->buffer[prod->writepos] = data;
prod->writepos++;
if(prod->writepos >= BUFFER_SIZE)
prod->writepos = 0;
pthread_cond_signal(&prod->notempty);
pthread_mutex_unlock(&prod->lock);
}
int get(struct prodcons* prod)
{
int data;
pthread_mutex_lock(&prod->lock);
while(prod->writepos == prod->readpos)
{
printf("consumer wait for not empty\n");
pthread_cond_wait(&prod->notempty, &prod->lock);
}
data = prod->buffer[prod->readpos];
prod->readpos++;
if(prod->readpos >= BUFFER_SIZE)
prod->readpos = 0;
pthread_cond_signal(&prod->notfull);
pthread_mutex_unlock(&prod->lock);
return data;
}
#define OVER (-1)
struct prodcons buffer;
void* producer(void* arg)
{
int n;
for(n=1; n<=5; ++n)
{
printf("producer sleep 1 second ....\n");
sleep(1);
printf("put the %d product\n", n);
put(&buffer, n);
}
for(n=6; n<=10; ++n)
{
printf("producer sleep 1 second ....\n");
sleep(3);
printf("put the %d product\n", n);
put(&buffer, n);
}
put(&buffer, OVER);
printf("product stoped\n");
return NULL;
}
void* consumer(void* arg)
{
int d = 0;
while(1)
{
printf("consumer sleep 2 second ....\n");
sleep(2);
d = get(&buffer);
printf("get the %d product\n", d);
if(d == OVER)
break;
}
printf("consumer stopped\n");
return NULL;
}
int main(int argc, char* argv[])
{
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("the retval %d\n", (int*)retval);
return 0;
}