c++互斥对象cout没有打印所有内容
c++ mutex cout not printing everything
我正在创建一个线程管理类,我可以向该类发布任务(函数+参数),该类将负责对它们进行线程处理。
这个问题与整个类没有太大关系(我认为),而是在使用多个线程时锁定共享资源的一般问题。这是代码:
主测试文件:
#include <iostream>
#include <thread>
#include <vector>
#include "Ttask_1.h"
#include <mutex>
using namespace std;
bool quit=false;
void* square(void* n);
void* print(void* n);
mutex cout_mutex;
mutex res_mutex;
bool cout_locked=false;
vector<Ttask_1<void*,void*>*> tasks1;
vector<Ttask_1<void*,void*>*> tasks2;
void check_for_work(vector<void*> &vec,vector<Ttask_1<void*,void*>*> &tasks)
{
while(!quit)
{
if(tasks.size()!=0)
{
(*tasks[0]).run(vec);
tasks.erase(tasks.begin());
}
else
quit=true;
}
while(cout_locked){}
cout_locked=true;
cout<<"thread done"<<endl;
cout_locked=false;
}
int main(int argc, const char * argv[])
{
vector<void*> vec;
int n=5;
//int *n_p=&n;
//Ttask_1<void*,void*> task(&n,square);
tasks1.push_back(new Ttask_1<void*,void*>(&n,square,true));
tasks1.push_back(new Ttask_1<void*,void*>(&n,print,false));
tasks2.push_back(new Ttask_1<void*,void*>(&n,square,true));
tasks2.push_back(new Ttask_1<void*,void*>(&n,print,false));
thread Thread1(check_for_work,ref(vec),ref(tasks2));
thread Thread2(check_for_work,ref(vec),ref(tasks1));
//(&Ttask_1<int,int>::run,&task,ref(vec));
// task.run(vec,Thread);
Thread1.join();
Thread2.join();
int a;
cin>>a;
return 0;
}
void* print(void* n)
{
for(int i=0;i<*(int*)(n);i++)
{
while(cout_locked){}
cout_locked=true;
cout<<i<<endl;
cout_locked=false;
}
void* a;
return a;
}
void* square(void* n)
{
int res=(*(int*)n)*(*(int*)n);
while(cout_locked){}
cout_locked=true;
cout<<res<<endl;
cout_locked=false;
int *res_p=new int;
res_p=&res;
return res_p;
}
ttask_1类:
#ifndef task_Test_Ttask_1_h
#define task_Test_Ttask_1_h
#include <vector>
#include <mutex>
using namespace std;
extern mutex res_mutex;
template <class type1, class ret>
class Ttask_1
{
public:
Ttask_1(type1 arg_in,ret(*func_p_in)(type1),bool result)
{
safe_result=result;
arg1=arg_in;
func_p=func_p_in;
}
void run(vector<void*> &res_vector)
{
ret res=(*func_p)(arg1);
if(safe_result)
{
void *res_p=&res;
res_mutex.lock();
res_vector.push_back(res_p);
res_mutex.unlock();
}
done=true;
}
bool is_done(){return done;}
private:
bool safe_result;
bool done=false;
type1 arg1;
ret(*func_p)(type1);
};
#endif
正如您所看到的,在看到互斥锁不起作用后,我在cout上实现了自己的"锁定"功能。行为完全相同,所以这不是问题所在。
这种行为如下:
我希望在程序终止之前,数字0,1,2,3,4,25和字符串"thread done"都打印两次。
然而,我经常(不总是,但经常)得到这样的输出:
25 0 1 2 3 4线程完成线程完成
所以少了几个数字,我不知道是什么原因造成的。正如我所说,eve如果我更换我自己的
while(cout_locked){}
cout_locked=true;
通过
cout_mutex.locked();
和
cout_locked=false;
通过
cout_mutex.unlock()
没有任何变化。
如有任何帮助,我们将不胜感激,感谢
您的主要问题是quit
是一个全局变量。一旦一个线程完成,另一个线程就不会再做任何工作(可能包括根本不做任何工作)。每个线程都需要一个quit
样式的变量,或者只使用size
检查作为while循环的条件。
您还将局部变量的地址放入run
函数中的vector
中,因此结果可能不可预测。为什么不让结果向量实际上是类型安全的?
也就是说,您的代码存在许多功能性和惯用性问题:
cout_locked
变量似乎只起作用,存在竞争条件——但我实际上根本不确定cout
是否需要锁定- 您将一切视为
void*
,丢弃了C++提供的大量类型安全性(如果您允许的话) - 您可以将类内初始化与构造函数初始化混合使用(为什么不在构造函数中初始化
done
呢) - 通常更喜欢构造函数初始值设定项列表,而不是构造函数体中的赋值,以防止构造后赋值的性能影响
- 从矢量开始
erase
,这是从矢量中擦除效率最低的位置。如果它代表一个队列,则根据您的需要使用queue
或deque
- CCD_ 13返回一个随机指针。如果您需要它返回
void*
,至少让它始终返回null(0
)
此代码返回一个指向局部变量的指针。访问此变量时,它将超出范围。它还会泄漏内存。
int *res_p=new int;
res_p=&res;
return res_p;
您需要使用值构造新的int
,而不是使用&
获取本地的地址。
return new int(res_p);
您还需要在访问任务向量时锁定
相关文章:
- 将对象放入地图后打印对象
- 打印对象的映射,其中另一个对象作为键
- 如何在C++中打印对象向量的内容
- C++ - 使用 std::list,如何打印对象的私有成员的链接列表?
- 使用成员函数打印对象
- 如何在C++中转换可打印对象中的对象
- 打印对象矢量的意外输出
- 如何使用 is_invocable() 创建用于重载<<打印对象的模板?
- 运算符重载<<,打印对象矢量时遇到问题
- 我正在尝试循环浏览对象的向量并打印对象的每个元素
- 在更改对象值后,打印对象数组仍会给出相同的值
- 声明并使用静态列表来打印对象(在c++中)
- 为什么写入临时字符串流对象只打印对象地址
- 打印对象数组
- 有没有一种方法可以打印对象的位表示
- OpenCV - 仅在绘制单应性时打印对象名称
- 在矢量 C++ 中可视化打印对象中的对象
- 使用 cout 打印对象指针值时地址长度不同
- C++模板打印对象名称
- 使用 c++ 中的重载运算符<<打印对象的动态数组