分析:
1.生产者每生产一个放到公共区域,消费者在满足一定条件时,才在公共区域消费,如果条件不满足,则堵塞,调动pthread_cond_wait()函数。
2.生产者生产完需要唤醒消费者去公共区域消费,此时调用pthread_cond_signal()或pthread_cond_broadcast(),唤醒堵塞在条件变量上的线程。
3.消费者需要:
①创建锁 pthread_mutex_t mutex
②初始化锁 pthread_mutex_init(&mutex,NULL)
③加锁 pthread_mutex_lock(&mutex)
④等待条件满足 pthread_cond_wait(&cond,&mutex)
⑤访问关系数据
⑥解锁,释放锁,释放条件变量
4.生产者需要:
①生产数据
②加锁 pthread_mutex_lock(&mutex)
③将数据放置到公共区域里
④解锁pthread_mutex_unlock(&mutex)
⑤通知阻塞在条件变量上的线程 pthread_cond_signal()或pthread_cond_broadcast()
⑥循环生产数据
代码:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
#include<errno.h>
void err_thread(int ret,char* str)
{
if(ret != 0)
{
fprintf(stderr,"%s:%s\n",str,strerror(ret));
pthread_exit(NULL);
}
}
struct msg{
int num;
struct msg* next;
};
struct msg* head;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//定义并初始化互斥锁
pthread_cond_t has_data = PTHREAD_COND_INITIALIZER;//定义并初始化条件变量
void* produster(void* arg)
{
while(1){
struct msg* mp = (struct msg*)malloc(sizeof(struct msg));
mp -> num = rand()%1000 + 1;//模拟生产一个数据
printf("---produster is %d\n",mp -> num);
pthread_mutex_lock(&mutex);//加锁
mp -> next = head;
head = mp;//写公共区域
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&has_data);
sleep(rand()%3);
}
return NULL;
}
void* consumer(void* arg)
{
while(1){
struct msg* mp;
pthread_mutex_lock(&mutex);//加锁
while(head == NULL)
{
pthread_cond_wait(&has_data,&mutex);//阻塞等待条件变量,解锁,pthread_cond_wait返回时重新加锁
}
mp = head;
head = mp -> next;
pthread_mutex_unlock(&mutex);
printf("consumer is %d,ID is %lu\n",mp -> num,pthread_self());
free(mp);
sleep(rand()%3);
}
return NULL;
}
int main()
{
pthread_t pid,cid;
int ret;
srand(time(NULL));
ret = pthread_create(&pid,NULL,produster,NULL);//创建生产者线程
if(ret != 0)
{
err_thread(ret,"pthread_create produster error");
}
ret = pthread_create(&cid,NULL,consumer,NULL);//创建消费者者线程
if(ret != 0)
err_thread(ret,"pthread_create consumer error");
ret = pthread_create(&cid,NULL,consumer,NULL);//创建消费者者线程
if(ret != 0)
err_thread(ret,"pthread_create consumer error");
ret = pthread_create(&cid,NULL,consumer,NULL);//创建消费者者线程
if(ret != 0)
err_thread(ret,"pthread_create consumer error");
pthread_join(pid,NULL);
pthread_join(cid,NULL);
}