C++ 线程工作不正常
我有一个C++ 线程工作不正常,c++,multithreading,mutex,C++,Multithreading,Mutex,我有一个类机器,带有一些成员函数。在makeProduct中,我创建了一个线程,该线程调用t\u make,然后returns。当线程在成员函数中执行其工作时,我仍然希望使用机器(状态检查、资源剩余等) 我是这样开始的 //machine.h private int stat; std::thread t; std::mutex m; bool working; //machine.cpp int Machine::makeProduct(){ if(
类机器
,带有一些成员函数。在makeProduct
中,我创建了一个线程,该线程调用t\u make
,然后return
s。当线程在成员函数中执行其工作时,我仍然希望使用机器
(状态检查、资源剩余等)
我是这样开始的
//machine.h
private
int stat;
std::thread t;
std::mutex m;
bool working;
//machine.cpp
int Machine::makeProduct(){
if(working == true) return -1;
t = std::thread(&Machine::t_make, this);
return 0;
}
void Machine::t_make(){
std::lock_guard<std::mutex> guard(m);
//do some time-consuming work, change "stat" in progress
}
void Machine::Status(int &copStat){
copStat = stat;
}
Machine::~Machine(){ if(t.joinable()) t.join; }
//main.cpp
...
Machine m;
m.makeProduct();
int getStat = 0;
m.Status(getStat);
if(getStat == 1) cout<< "Product in making";
//machine.h
私有的
int stat;
标准:螺纹t;
std::互斥m;
布尔工作;
//machine.cpp
int Machine::makeProduct(){
if(working==true)返回-1;
t=std::thread(&Machine::t_make,this);
返回0;
}
void Machine::t_make(){
标准:锁紧装置(m);
//做一些耗时的工作,更改正在进行的“stat”
}
无效计算机::状态(int和copStat){
copStat=stat;
}
机器::~Machine(){if(t.joinable())t.join;}
//main.cpp
...
机器m;
m、 makeProduct();
int getStat=0;
m、 状态(getStat);
如果(getStat==1)在调用getProduct()之后立即调用Status()时不能,那么很可能新线程还没有开始执行任何操作。您仍然处于原始线程中,必须设置新线程并开始运行
您加入析构函数对于本练习来说并没有实际意义。如果您想确保收集结果,并在机器超出范围时对其进行处理,这可能是有意义的,但对于您关于检查状态的问题没有意义。如果希望Status()只在t_make()完成后返回值,那么将join()代码移动到Status就行了
看看常设线程库中的未来。这些是用于执行异步任务并在任务完成时获得结果的实用程序。如果t_make正在修改“stat”,则您的状态函数应在分配copStat时使用“stat”之前获取锁。内存访问当前不安全
目前的代码是,如果您希望在调用Status之前完成t_make调用,那么没有什么强迫您这样做。实际上,两个独立的线程将自动完成这些操作—1个线程调用t_make,1个线程调用Status。无法保证这种情况发生的顺序。(如果向状态添加锁,则会发生更改)
另外,您能否更新您的示例,以显示您如何确定从不填充copStat?您能否创建一个实例并向我们展示?因为现在很难理解你截取的代码是如何协同工作的。特别重要的是要知道如何使用机器
类。而且您显示的代码将无法按预期工作(您没有调用join
函数)。文件太大:/我将尝试添加更多。关于join
函数,我在析构函数中调用它。@TheGuyWithTreetCred您遗漏了“()”。在joinable
上。看起来您在stat
(可能还有working
)变量上有竞争条件。尝试并std::atomic
。如果我在定义t
之后插入sleep(1)
,它工作正常。这能让你明白吗?这正是我们要说的。您正在任务完成前调用Status()。添加睡眠(1)可以完成任务。如果希望Status()给出最终答案(而不是赋值过程中的某个中间值),则需要Status()函数中的同步。