gpt4 book ai didi

c++ - 使用两个线程和 boolean 值的奇怪问题

转载 作者:太空宇宙 更新时间:2023-11-04 13:48:24 26 4
gpt4 key购买 nike

(我讨厌不得不用这样的标题。但我找不到更好的标题)

我有两个类和两个线程。第一个检测两帧之间的运动:

void Detector::run(){

isActive = true;

// will run forever
while (isActive){

//code to detect motion for every frame
//.........................................

if(isThereMotion)
{
if(number_of_sequence>0){

theRecorder.setRecording(true);
theRecorder.setup();

// cout << " motion was detected" << endl;

}
number_of_sequence++;
}
else
{
number_of_sequence = 0;
theRecorder.setRecording(false);
// cout << " there was no motion" << endl;
cvWaitKey (DELAY);

}
}
}

第二个将在开始时录制视频:

void Recorder::setup(){

if (!hasStarted){
this->start();
}
}

void Recorder::run(){

theVideoWriter.open(filename, CV_FOURCC('X','V','I','D'), 20, Size(1980,1080), true);


if (recording){

while(recording){
//++++++++++++++++++++++++++++++++++++++++++++++++
cout << recording << endl;
hasStarted=true;
webcamRecorder.read(matRecorder); // read a new frame from video
theVideoWriter.write(matRecorder); //writer the frame into the file

}

}
else{
hasStarted=false;
cout << "no recording??" << endl;
changeFilemamePlusOne();
}
hasStarted=false;
cout << "finished recording" << endl;
theVideoWriter.release();

}

boolean 记录被函数改变:

void Recorder::setRecording(bool x){
recording = x;
}

目标是在检测到运动后开始录制,同时防止程序开始录制两次。

真正奇怪的问题是,老实说,我脑子里没有任何意义,代码只有在我计算出 boolean 记录(标有“++++++”)时才能工作。 Else 记录永远不会更改为 false,else 语句中的代码永远不会被调用。

有没有人知道为什么会这样。我仍然只是从 C++ 开始,但这个问题对我来说真的很奇怪..

最佳答案

我想你的变量isThereMotionrecordingbool 类型的简单类成员.

默认情况下,对这些成员的并发访问不是线程安全的,您将面临竞争条件和各种奇怪的行为。

我建议像这样声明这些成员变量(只要你能使用最新的标准):

class Detector {
// ...
std::atomic<bool> isThereMotion;
};

class Recorder {
// ...
std::atomic<bool> hasStarted;
};

等等

背后的原因是,即使读/写一个简单的 boolean 值也会拆分成几个应用于 CPU 的汇编程序指令,并且这些指令可能会在中间被调度以用于进程的线程执行路径更改。使用 std::atomic<>提供类似临界区的东西,用于自动对此变量进行读/写操作。


简而言之:将旨在从不同线程并发访问的所有内容都设为原子值,或者使用适当的同步机制,如 std::mutex .

如果您不能使用最新的 c++ 标准,您或许可以使用 boost::thread 来解决问题以保持代码的可移植性。


注意:
从你的评论来看,你的问题似乎是针对 Qt 框架的,有许多机制可以用于同步,例如提到的 QMutex .


为什么 volatile在多线程环境中没有帮助?

volatile防止编译器仅通过假设以前按顺序设置的值来优化实际的读取访问。它不会阻止线程在实际检索或写入值时被中断。

volatile应该用于读取可以独立于顺序或线程执行模型更改的地址(例如总线寻址的外围硬件寄存器,其中硬件主动更改值,例如 FPGA 在寄存器接口(interface)上报告当前数据吞吐量)。

在此处查看有关此误解的更多详细信息:
Why is volatile not considered useful in multithreaded C or C++ programming?

关于c++ - 使用两个线程和 boolean 值的奇怪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24684400/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com