LINUX 线程锁的设置不当案例(生产者消费者模型小BUG)
2016-11-03 17:36
471 查看
先上错误代码:
#include"../h.h"
#include<list>
#include<iostream>
typedef struct tasks
{
int a;
}tasks;
pthread_mutex_t mutex;
pthread_cond_t con;
std::list<tasks*> queue;
void * work_thread(void *p)
{
while(1)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&con,&mutex);
printf("****\n");
pthread_mutex_unlock(&mutex);
while(1)
{
pthread_mutex_lock(&mutex);
if(queue.size()==0)
{
pthread_mutex_unlock(&mutex);
break;
}
std::list<tasks*>::iterator it = queue.begin();
tasks* task = *it;
printf("task is :%d\n",task->a);
delete task;
printf("*******delete*****\n");
queue.pop_front();
pthread_mutex_unlock(&mutex);
}
}
}
int main()
{
pthread_t work_t;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&con,NULL);
pthread_create(&work_t,NULL,work_thread,NULL);
while(1)
{
pthread_mutex_lock(&mutex);
// printf("main lock\n");
int a;
std::cin >> a;
tasks* task = new tasks;
task->a= a;
queue.push_back(task);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&con);
printf("send signal OK\n");
}
return 0;
}
执行结果:
1 //输入数字
send signal OK
分析:主线程发信号之后子线程没有执行接收信号,一遍遍检查代码OK,扯掉一把头发之后,试着把加锁的位置换到了cin之后,OK了;
分析2:cin语句是阻塞的,而进程只有一把锁,主线程可以一直执行,子线程一直不能接收到信号,接收信号首先要得到锁,所以当加入cin之后必然是子线程可以得到锁,代码才可以继续执行;
主函数获得锁之后打印 printf("main lock\n");可以看到,发送信号之后主线程马上又获得了锁,导致子线程一直不能执行;
执行结果:
1
send signal OK
main lock
结论:
一般只在使用锁之前需要先安排好获得锁的顺序,且一般只在操作全局变量的时候加锁,可以提高效率;
主函数改为:
int main()
{
...
while(1)
{
int a;
std::cin >> a;
tasks* task = new tasks;
task->a= a;
pthread_mutex_lock(&mutex);
queue.push_back(task);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&con);
printf("send signal OK\n");
}
return 0;
}
#include"../h.h"
#include<list>
#include<iostream>
typedef struct tasks
{
int a;
}tasks;
pthread_mutex_t mutex;
pthread_cond_t con;
std::list<tasks*> queue;
void * work_thread(void *p)
{
while(1)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&con,&mutex);
printf("****\n");
pthread_mutex_unlock(&mutex);
while(1)
{
pthread_mutex_lock(&mutex);
if(queue.size()==0)
{
pthread_mutex_unlock(&mutex);
break;
}
std::list<tasks*>::iterator it = queue.begin();
tasks* task = *it;
printf("task is :%d\n",task->a);
delete task;
printf("*******delete*****\n");
queue.pop_front();
pthread_mutex_unlock(&mutex);
}
}
}
int main()
{
pthread_t work_t;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&con,NULL);
pthread_create(&work_t,NULL,work_thread,NULL);
while(1)
{
pthread_mutex_lock(&mutex);
// printf("main lock\n");
int a;
std::cin >> a;
tasks* task = new tasks;
task->a= a;
queue.push_back(task);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&con);
printf("send signal OK\n");
}
return 0;
}
执行结果:
1 //输入数字
send signal OK
分析:主线程发信号之后子线程没有执行接收信号,一遍遍检查代码OK,扯掉一把头发之后,试着把加锁的位置换到了cin之后,OK了;
分析2:cin语句是阻塞的,而进程只有一把锁,主线程可以一直执行,子线程一直不能接收到信号,接收信号首先要得到锁,所以当加入cin之后必然是子线程可以得到锁,代码才可以继续执行;
主函数获得锁之后打印 printf("main lock\n");可以看到,发送信号之后主线程马上又获得了锁,导致子线程一直不能执行;
执行结果:
1
send signal OK
main lock
结论:
一般只在使用锁之前需要先安排好获得锁的顺序,且一般只在操作全局变量的时候加锁,可以提高效率;
主函数改为:
int main()
{
...
while(1)
{
int a;
std::cin >> a;
tasks* task = new tasks;
task->a= a;
pthread_mutex_lock(&mutex);
queue.push_back(task);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&con);
printf("send signal OK\n");
}
return 0;
}
相关文章推荐
- 谈谈我对Linux下“生产者/消费者线程模型”的理解
- Linux——线程锁实现的生产者、消费者模型
- 谈谈我对Linux下“生产者/消费者线程模型”的理解
- 第23章 java线程通信——生产者/消费者模型案例
- Linux线程--生产者消费者模型
- Linux C:利用两个线程实现生产者消费者模型
- 【Linux】线程总结:线程同步 -互斥锁,条件变量,信号量实现多生产者多消费者模型
- java线程-从生产者和消费者模型说起
- 生产者与消费者模型案例
- 生产者、消费者线程模型 java版
- 线程同步之经典生产者-消费者模型
- Java线程:并发协作-生产者消费者模型
- 从java多线程实现“生产者-消费者”模型来谈谈操作系统中线程状态的转换及线程同步的总结
- Java线程:并发协作-生产者消费者模型 转自:http://lavasoft.blog.51cto.com/62575/221932
- JAVA 线程通信以及多个生产者消费者模型
- 线程同步之经典生产者-消费者模型
- Java线程:并发协作-生产者消费者模型
- 【多线程】_线程操作案例——生产者和消费者笔记
- Java线程:并发协作-生产者消费者模型
- linux c pv 实现生产者消费者模型