带有GCC的C++11中的线程范围对象
Thread-scoped objects in C++11 with GCC
考虑以下C++11程序:
struct S {
S() {/* do something */ }
} global_object;
int main() {
}
我还没有GCC 4.8
要测试,但从我读到的关于C++11标准的内容来看,无论我是否将全局对象声明为thread_local
,对象本身都将为程序执行期间可以创建的所有可能线程实例化一次。
GCC中是否有一种方法(可移植或不可移植)可以在每次一个线程启动时实例化和约束全局对象,并在每次同一线程结束时销毁全局对象?
但从我读到的关于C++11标准的内容来看,无论我是否将全局对象声明为
thread_local
,对于程序执行过程中可以创建的所有可能的线程,对象本身都会实例化一次
这不是C++11标准所说的。C++11标准(草案n3337)的相关章节:
- 3.7.2线程存储时间,第1条:
所有用
thread_local
关键字声明的变量都具有线程存储持续时间。这些实体的存储应在创建它们的线程期间持续每个线程都有一个不同的对象或引用,使用声明的名称是指与当前线程关联的实体。
- 7.1.1存储类别说明符,第4条:
thread_local
说明符表示命名实体具有线程存储持续时间(3.7.2)。它应仅应用于命名空间或块作用域的变量名称以及静态数据成员的名称当thread_local应用于块作用域的变量时,如果存储类说明符static没有显式显示,则它是隐含的。
它没有指出,如果在全局命名空间中用thread_local
定义了一个对象,那么只会创建它的一个实例。Jesse Good已经发布的另一个例子打印了全局对象的每个实例的唯一地址(见在线演示):
#include <iostream>
#include <thread>
#include <vector>
struct S {};
thread_local S global_s;
int main()
{
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i)
threads.push_back(std::thread([](){ std::cout << &global_s << 'n'; }));
for (auto& t: threads) t.join();
}
输出:
0x4165993f0x4205a93f0x4485e93f0x42a5b93f0x4525f93f0x45c6093f0x4666193f0x4706293f0x43e5d93f0x4345c93f
无论我是否将全局对象声明为thread_local
你试过了吗?我非常确信它将为每个线程创建一个单独的实例。
请参阅coliru上的以下代码:
struct S {
int i = 0;
S() {}
};
thread_local S global;
int main()
{
std::thread t1([](){global.i = 1; std::cout << global.i << std::endl;});
t1.join();
std::cout << global.i << std::endl;
std::thread t2([](){global.i = 2; std::cout << global.i << std::endl;});
t2.join();
std::cout << global.i << std::endl;
std::thread t3([](){global.i = 3; std::cout << global.i << std::endl;});
t3.join();
std::cout << global.i << std::endl;
}
它输出:
1
0
2
0
3
0
相关文章:
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 超出范围时使用对象
- 如何访问超出其块范围的对象?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 对象超出范围/转让所有权
- 从函数返回范围视图时,带有std::span:中间对象所有权的C++Ranges-v3
- 读取互斥对象范围之外的volatile变量,而不是std::atomic
- 是否可以在C++ (C) 中使用全局范围对象(结构)?
- 基于范围的 for 循环将对象移动到另一个容器中?
- 对象超出范围后,引用成员设置为 0
- 哪个函数负责C++全局范围内的类对象初始化?
- 非常量对象的向量似乎在基于范围的 for 循环中被视为常量
- 如果一个对象是在本地创建的,并在C++中作为异常抛出,那么本地对象如何在其范围之外有效,即在 catch 块中?
- 是否有一种方法可以根据派生的可能性值范围限制对象参数
- 类对象未在范围中声明
- 如何打印出唯一指针对象向量中的值(基于范围的循环)?C++
- 基于范围的 for 循环,用于包含C++中的指针的自定义链表,仅返回对象
- 带有GCC的C++11中的线程范围对象
- C++ / GCC - 未调用文件范围对象的构造函数