只要不使用其他.cpp文件,静态原子变量就可以跨线程工作.其他方面它会以某种方式阻止写访问吗
static atomic variable works across threads as long as no other .cpp files are utilized other wise it blocks write access somehow?
我正在学习多线程,下面有一个简单的程序来显示一些进展。我不明白为什么函数在.h文件或main.cpp文件中定义的第一个代码工作得很好。但是,如果我把startLineThread的定义放在一个新的.cpp文件中,比如tools.cpp,那么第二个线程似乎永远不会有机会写入calcProgress变量,尽管它是静态的。控制台只循环使用零,还忽略设置为false的计算bool标志,我可以在调试一段时间后看到第二个循环中的循环完成并打印";完成";到控制台,但main中的while循环会忽略Tools::computing==false并保持循环。
------------------------- tools.h with definition within it ----------------------------
#pragma once
#include <atomic>
#include <iostream>
#include "tools.h"
#include <thread>
#include <chrono>
namespace Tools
{
static std::atomic<float> clacProgress;
static volatile bool cFinished;
static volatile bool calculating;
void startLineThread()
{
std::cout << " second thread active " << std::endl;
float dataPoints = 1000;
float dt = 0.5;
for (float t = 0.0f; t < dataPoints; t++)
{
// bs code for making this thread slightly slower maybe
float no = 87 + 45;
int slow = 45 * 56 * 23;
std::this_thread::sleep_for(std::chrono::microseconds(8));
Tools::clacProgress = t;
}
//Tools::cFinished = true;
Tools::calculating = false;
std::cout << "done" << std::endl;
}
}
// this way works fine calcProgress is incremented and printed with updated value
// and the while loop in main exits when calculating becomes false;
-------------------------------main.cpp ----------------------------------------
#include <vector>
#include <string>
#include <stdio.h>
#include <math.h>
#include <chrono>
#include <sstream>
#include <thread>
#include "tools.h"
#include <atomic>
int main()
{
std::cout << " main thread active " << std::endl;
// initilize all statics before any other threads are active
//Tools::clacProgress = 0;
Tools::calculating = true;
Tools::cFinished = false;
std::thread testCalc(Tools::startLineThread);
while ( Tools::calculating)
{
std::cout << Tools::clacProgress << std::endl;
std::this_thread::sleep_for(std::chrono::microseconds(200));
}
std::cin.get();
}
------------------------------------------------------------------------------
现在,如果我把startLineThread的定义放在tools.cpp文件中,它会破坏一切。
---------------------------- tools.h startLineThread declared but not defined -------
#pragma once
#include <atomic>
namespace Tools
{
static std::atomic<float> clacProgress;
static volatile bool cFinished;
static volatile bool calculating;
void startLineThread();
}
----------------------------- tools.cpp ------------
#include <iostream>
#include "tools.h"
#include <thread>
#include <chrono>
void Tools::startLineThread()
{
std::cout << " second thread active " << std::endl;
float dataPoints = 1000;
float dt = 0.5;
for (float t = 0.0f; t < dataPoints; t++)
{
// bs code for making this thread slightly slower maybe
float no = 87 + 45;
int slow = 45 * 56 * 23;
std::this_thread::sleep_for(std::chrono::microseconds(8));
Tools::clacProgress = t;
}
//Tools::cFinished = true;
Tools::calculating = false;
std::cout << "done" << std::endl;
}
/* this way calcProgress is never incremented in the main thread and prints zero's despite the second thread kicking off and looping and I see " done " printed which indicates it did loop and the while loop in main never exits despite calculating becoming false */
-------------------------------main.cpp ----------------------------------------
#include <vector>
#include <string>
#include <stdio.h>
#include <math.h>
#include <chrono>
#include <sstream>
#include <thread>
#include "tools.h"
#include <atomic>
int main()
{
std::cout << " main thread active " << std::endl;
// initilize all statics before any other threads are active
//Tools::clacProgress = 0;
Tools::calculating = true;
Tools::cFinished = false;
std::thread testCalc(Tools::startLineThread);
while ( Tools::calculating)
{
std::cout << Tools::clacProgress << std::endl;
std::this_thread::sleep_for(std::chrono::microseconds(200));
}
std::cin.get();
}
------------------------------------------------------------------------------
如果这是一种比赛条件,我不明白为什么我在一种情况下会有这种情况,而不是另一种情况?但我认为静态原子会阻止线程更新/报告进度值的竞争条件
这些变量不应该在头文件中定义:
static std::atomic<float> clacProgress;
static volatile bool cFinished;
static volatile bool calculating;
通过在头中定义它们,您可以为每个.cpp文件中的每个变量制作一个单独的副本。假设您使用的是C++17或更新版本,请将static
更改为inline
。如果您使用的是C++14或更低版本,请将static
更改为extern
,然后在.cpp文件中定义变量(因此每个变量都有一个副本,请参阅头文件C++中的声明变量(。
相关文章:
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 为什么这个选择排序算法仍然切换一个元素,当它已经是其他元素中最小的元素时?
- 如何在线程中初始化对象,然后在其他地方使用它?
- 当只有一个线程主要使用该对象而其他线程很少使用它时,如何最小化该对象的互斥锁锁定?
- 在命名空间中声明变量,在 main 中定义它,使其对所有其他文件可见
- 当我尝试将范围值存储为 8 位的固定宽度整数时,它向我显示一些其他值 [ASCII]
- 生成线程并在运行时执行其他操作,只要它处于活动状态
- 删除提升interprocess_mutex,当其他进程可能正在使用它时
- 如果我具有调用其其他实例之一的超载函数,它是否被认为是递归功能
- 将 2D 数组设置为函数,并根据需要在其他地方调用它
- 不太明白 & 运算符的地址在这个结构中做什么,以及它如何能够访问其他成员变量
- 如何在保持多态性的同时,将成员函数添加到需要它的继承类中,而不会影响其他同级类?
- 将std ::函数铸造到其他std ::功能并调用它
- 在函数指针中传递给其他线程的对象 - 如何处理它
- 在源文件中定义数组,然后在其他源文件中使用它
- Android NativeActivity.如何在其他方面做一些工作
- 在其他方面等效的有符号和无符号类型的别名
- 我的函数显示垃圾,其他时候它显示干净的结果
- rand()有时会输出空行,其他时候它也可以正常工作