螺纹在循环中冻结
Thread freezing in a while loop
在GCC中进行编译以进行释放时,我会在算法中使用线程奇怪的行为。即使WILE条件发生变化,该线程也不会离开等待循环,好像只是死了。
我注意到的另一件事是,如果将std::this_thread.sleep_for(10ms)
插入在等待循环中,则可以正常工作,或者如果我进行调试,则也可以正常工作。
以下(伪)代码是代码的非常简化的版本。
bool some_data_ready = false;
bool lets_plot_data = false;
bytearray packets; // a dynamic bytearray that holds a stream of packets
void decode(){
while(1){
if(packets.size() > 200){ // packets has data to be decoded
while (lets_plot_data) { //waiting loop
/* on the second run it gets stuck here becuse thread 1 dont
* leave its locking loop even if lets_plot_data changes
*/
//this_thread.sleep_for(10ms);
}
for(int i = 0;i< packets.size();++i){
if(packets.at(i) == 255){
if(packets.at(i+15) == 200){
//checks if packet has a start and an end
if(packets.at(14) == xor_checksum(packets.at(i))){
//packet is valid if calculated checksum is equal to the packet checksum
some_data_ready = true;
plot_data.push(packets.mid(i,15)); // copy a section starting at i len 15
// gets a packet and push it do be plotted
}
}
}
}
if(some_data_ready){
lets_plot_data = true;
some_data_ready = false;
}
}
}
}
void plot(){
while(1){
while (!lets_plot_data) { //thread dont leave here even if lets_plot_data changes
//this_thread.sleep_for(10ms);
}
graph.plot(plot_data); // not relevant, plots data at a graph
lets_plot_data = false;
}
}
std::thread* thread0;
std::thread* thread1;
std::thread* thread2;
int main(void){
thread0 = new std::thread(data); // gets data to be decoded (stream of ubytes containing packets)
thread1 = new std::thread(plot); // plot decoded data
thread2 = new std::thread(decode); // decodes data to be ploted
while(1){
//"gui loop"
}
return 0;
}
如果想知道,我对GCC的发布标志是
-Ofast -msse -fomit-frame-pointer -fmodulo-sched -fmodulo-sched-allow-regmoves -fgcse-sm -fgcse-las -fgcse-after-reload -funsafe-loop-optimizations -flive-range-shrinkage -fsched-spec-load-dangerous -fsched2-use-superblocks -floop-nest-optimize -floop-parallelize-all -ftree-parallelize-loops=8 -fprefetch-loop-arrays -ffinite-math-only -march=native -mtune=native -mfpmath="387+sse" -std=c++17 -lstdc++ -static
但仅适用于-O2
,与-g -Og
一起工作正常,就像看起来很奇怪
感谢您的关注。
在您的标志上有一个明显的竞赛条件:您在执行plot()
的线程和执行decode()
的线程中读取和写入lets_plot_data
。
您需要声明这些标志原子:
atomic<bool> some_data_ready { false };
atomic<bool> lets_plot_data { false };
如果您还不熟悉这种问题,我建议您从Herb Sutter观看此视频。
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 了解如何在不冻结事件循环的情况下在 QThread 中休眠/等待
- 在 openGL 中播放音频而不冻结绘制循环
- 螺纹在循环中冻结
- 程序冻结/循环
- 如何创建非冻结无限循环
- 确定在时间关键型循环中冻结 200 毫秒的原因
- 即使使用另一个线程,启动while循环也会冻结程序
- c++格式在while循环期间冻结