想实现线程的同步,解决消费者问题,利用互斥锁,发现不能成功,也许还要加其他的只是,
#include <stdio.h>
#include<pthread.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
typedef struct
{
int product[5];
int count;
}
PRODUCT;
PRODUCT buffer;//缓冲区结构,消费者和生产者共同操作
pthread_mutex_t mutex;//创建互斥锁
pthread_t tid;//新线程号
pthread_t tid_m;//主线程号
void consumer()//消费者函数
{
// while(1) //担心这个函数执行完了线程退出考虑加while(1)死循环,想在主函数用return终止这个线程,但是加上后只能写一次,读一次然后程序就不动了
//不加会先写一次,读一次,再写入两次。
{
pthread_mutex_lock(&mutex);//上锁
int i=buffer.count;
for(;buffer.count>0;buffer.count--)
{
printf("read %d is %d\n",buffer.count,buffer.product[i-buffer.count]);
}
pthread_mutex_unlock(&mutex);//解锁
pthread_join(tid_m,NULL);//等待生产者线程输入数据完毕 问题在这里 需要新的知识解决
}
}
void product()
{
pthread_mutex_lock(&mutex);//上锁
for(buffer.count=0;buffer.count<5;buffer.count++)
{
sleep((unsigned)rand()%3);//线程休眠
buffer.product[buffer.count]=rand()%10;
printf("write %d is %d \n",buffer.count,buffer.product[buffer.count]);
}
pthread_mutex_unlock(&mutex);//解锁
pthread_join(tid,NULL);//等待消费者线程 写数据完毕
}
int main()
{
int ret,i;
tid_m=pthread_self();//获取主线程的id
time_t t;
srand((unsigned)time(&t));//随机数模仿速度不固定
memset(&buffer,0,sizeof(PRODUCT));//先清空缓冲区
pthread_mutex_init(&mutex,NULL);//初始化互斥锁
ret=pthread_create(&tid,NULL,(void*)consumer,NULL);//创建新线程
if(ret!=0)
{
perror("ret");
exit(0);
}
for(i=0;i<3;i++)//写三次
{
product();
}
pthread_mutex_unlock(&mutex);//销毁互斥锁
return 0;
}
程序写入一次的时候,没有问题,但是写入三次的时候要么阻塞,要么不读去以后的写入,这里只是看到了互斥锁的特点,但是没有解决最终问题。还需要条件变量的知识。下面是修正后的程序,用到了条件变量,这个变量是用来对线程进行阻塞的。
#include <stdio.h>
#include<pthread.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define WRITE_TIMES 3 //生产次数
typedef struct
{
int product[5];
int count;
}
PRODUCT;
PRODUCT buffer;//缓冲区结构,消费者和生产者共同操作
pthread_mutex_t mutex;//创建互斥锁
pthread_cond_t cond;//创建条件变量
pthread_t tid;//新线程号
pthread_t tid_m;//主线程号
void consumer()//消费者函数
{
static int T=0;
int i=0;
while(T<WRITE_TIMES)
{
pthread_mutex_lock(&mutex);//上锁
while(buffer.count!=5)
{ //当初不知道pthread_cond_wait函数加在哪里,忽视了线程共享同一进程的资源。
pthread_cond_wait(&cond,&mutex);//等待信号
}
i=buffer.count;
for(;buffer.count>0;buffer.count--)
{
printf("read %d is %d\n",buffer.count,buffer.product[i-buffer.count]);
}
pthread_mutex_unlock(&mutex);//解锁
T++;
}
}
void product()
{
pthread_mutex_lock(&mutex);//上锁
for(buffer.count=0;buffer.count<5;buffer.count++)
{
// sleep((unsigned)rand()%2);//线程休眠,这里是模仿速度不固定,验证互斥锁是否其作用
buffer.product[buffer.count]=rand()%10;
printf("write %d is %d \n",buffer.count,buffer.product[buffer.count]);
}
pthread_cond_signal(&cond);//接触消费者线程的锁定状态
pthread_mutex_unlock(&mutex);//解锁
sleep(1);//必须有,否则CPU执行速度太快,生产者线程来不及切换,导致生产WRITE_MAX次,只消费一次
}
int main()
{
int ret,i;
tid_m=pthread_self();//获取主线程的id
time_t t;
srand((unsigned)time(&t));//随机数模仿速度不固定
memset(&buffer,0,sizeof(PRODUCT));//先清空缓冲区
pthread_mutex_init(&mutex,NULL);//初始化互斥锁
pthread_cond_init(&cond,NULL);//初始化条件变量
ret=pthread_create(&tid,NULL,(void*)consumer,NULL);//创建新线程
if(ret!=0)
{
printf("create thread fail \n");
exit(0);
}
for(i=0;i<WRITE_TIMES;i++)//生产WRITE——TIMES次
{
product();
}
pthread_join(tid,NULL);//等待消费者线程退出,生产者线程就是主线程,最后return退出
pthread_mutex_unlock(&mutex);//销毁互斥锁
pthread_cond_destroy(&cond);
return 0;
}
现在思考下第一次为什么失败,当初理解有误,pthread_join函数是等待线程退出,类似与进程里面的wait_pid函数,而我理解成了阻塞当前线程,是不对的,首先我在product里面,最后等待新的线程执行完,然后新的线程开始执行,但是新的线程执行了后,我又调用pthread_join等待主线程结束,我当时认为这是只是阻塞线程,CPU会进行调度的,其实这两个线程你等着我死,我等着你死,然后就出现了程序不继续运行的情况了。
下面才是正确的执行情况,写三次,读取三次。