现在C++正在添加thread_local存储作为语言功能,我想知道一些事情:
thead_local可能的成本是多少?
thread_local都必须为每个创建的线程提供特定于线程的存储空间.在我以这种方式声明变量之后:
#include <thread>
namespace thread_space
{
thread_local int s;
} //etc.
Run Code Online (Sandbox Code Playgroud)
我试图使用'g ++ -std = c ++ 0x -pthread [sourcefile]'编译我的代码.我收到以下错误:
example.C:6:8: error: thread-local storage is unsupported for the current target
static thread_local int s;
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用GCC 4.8.1在Linux上使用相同的标志编译相同的代码,我会得到一个正常运行的可执行文件.我在运行OSX 10.9.3的MacBook Pro上使用了clang-503.0.40(Xcode 5.1.1附带的那个).谁能解释一下我做错了什么?谢谢!!
在 lambda 中捕获 thread_local:
#include <iostream>
#include <thread>
#include <string>
struct Person
{
std::string name;
};
int main()
{
thread_local Person user{"mike"};
Person& referenceToUser = user;
// Works fine - Prints "Hello mike"
std::thread([&]() {std::cout << "Hello " << referenceToUser.name << std::endl;}).join();
// Doesn't work - Prints "Hello"
std::thread([&]() {std::cout << "Hello " << user.name << std::endl;}).join();
// Works fine - Prints "Hello mike"
std::thread([&user=user]() {std::cout << "Hello " << user.name << std::endl;}).join();
}
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/zeocG5ohb
看起来如果我使用 a 的原始名称,thread_local那么执行 …
这个程序:
#include <iostream>
struct Foo {
Foo() {
std::cout << "Foo()\n";
}
~Foo() {
std::cout << "~Foo()\n";
}
};
struct Bar {
Bar() {
std::cout << "Bar()\n";
}
~Bar() {
std::cout << "~Bar()\n";
thread_local Foo foo;
}
};
Bar bar;
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印
Bar()
~Bar()
Foo()
Run Code Online (Sandbox Code Playgroud)
对我来说(GCC 6.1,Linux,x86-64).永远不会调用~Foo().这是预期的行为吗?
c++ multithreading language-lawyer thread-local-storage c++11
我需要为每个将通过宏访问的线程存储一个唯一的指针.我认为我应该使用单例和静态thread_local std :: unique_ptr对象来解决这个问题.这是代码的简化版本:
#include <thread>
#include <vector>
#include <iostream>
#include <mutex>
using namespace std;
#include "yay.hpp"
mutex coutMutex;
void yay(int id)
{
int* yayPtr = getYay();
// I know this is bad
coutMutex.lock();
cout << "Yay nr. " << id << " address: " << yayPtr << endl;
coutMutex.unlock();
}
int main()
{
vector<thread> happy;
for(int i = 0; i < thread::hardware_concurrency(); i++)
{
happy.push_back(thread(yay, i));
}
for(auto& smile : happy)
{
smile.join();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用Go和Gin来设置我的网站,并想知道数据库访问时间.我使用goroutine所以如果不使用类似线程的东西,我必须改变几乎每个函数来做它.Go有很好的方法吗?
c ++编译器如何在C++ 0x中实现线程本地存储
我在谷歌搜索过这个.但我找不到任何关于此事的内容.
有没有人对此有任何材料?
使我无法定期使用Akka(使用Java)是我对使用ThreadLocals的库的一个担忧.
这就是我认为一些Akka Dispatchers可能会导致ThreadLocal变量被遗忘,或者一起丢失.所以显而易见的解决方案是避免使用ThreadLocals但是有很多库使用它们:Spring,Wro4j,Log4j等等......
ThreadLocals通常在Servlet容器中正常工作.这是因为即使容器有线程池,请求主要是一个同步生命周期,因此通常在请求结束时,像Spring和Wro4J这样的东西会清除那里的threadlocals.像Tomcat这样的容器甚至可以监控线程局部泄漏.
根据我的理解,Akka的情况并非如此.
人们如何解决这个问题?
现在我只是避免使用Akka并使用Message Queue(如RabbitMQ或ActiveMQ),但想使用Akka,因为它涵盖了更广泛的异步问题/解决方案.
我也认为Netty有类似的问题,但我相信Netty提供了一些可用于代替ThreadLocal的Channel Context对象,理论上一些库可能知道使用它而不是ThreadLocal.
Valgrind在以下代码中报告泄漏的块,显然是每个线程一个:
#include <iostream>
#include <thread>
#include <mutex>
#include <list>
#include <chrono>
std::mutex cout_mutex;
struct Foo
{
Foo()
{
std::lock_guard<std::mutex> lock( cout_mutex );
std::cout << __PRETTY_FUNCTION__ << '\n';
}
~Foo()
{
std::lock_guard<std::mutex> lock( cout_mutex );
std::cout << __PRETTY_FUNCTION__ << '\n';
}
void
hello_world()
{
std::lock_guard<std::mutex> lock( cout_mutex );
std::cout << __PRETTY_FUNCTION__ << '\n';
}
};
void
hello_world_thread()
{
thread_local Foo foo;
// must access, or the thread local variable may not be instantiated
foo.hello_world();
// keep the thread around momentarily
std::this_thread::sleep_for( …Run Code Online (Sandbox Code Playgroud) 我在链接期间发生了一个奇怪的问题.
我有一个包含以下定义的头文件foo.hpp:
struct Foo { static __thread int x; }
Run Code Online (Sandbox Code Playgroud)
以及引用该变量的源文件plugin.cpp:
#include "foo.hpp"
void bar() { int y = Foo::x; }
Run Code Online (Sandbox Code Playgroud)
编译很好:
$CXX -stdlib=libc++ -std=c++11 -fvisibility=hidden -fPIC -o plugin.cpp.o -c plugin.cpp
Run Code Online (Sandbox Code Playgroud)
但是当我尝试链接为动态库时:
$CXX -stdlib=libc++ -std=c++11 -fvisibility=hidden -dynamiclib -Wl,-undefined,dynamic_lookup -o libext.dylib ext.cpp.o
Run Code Online (Sandbox Code Playgroud)
我明白了:
ld:非法线程局部变量引用常规符号__ZN3Foo1xE,用于体系结构x86_64
但是llvm字节码意味着编译器正确地将其Foo::x视为TLS变量.
$CXX -stdlib=libc++ -std=c++11 -fvisibility=hidden -fPIC -S -emit-llvm -o -
... omitted
@_ZN3Foo1xE = external thread_local global i32
... omitted
; Function Attrs: nounwind ssp uwtable
define hidden void @_Z3barv() #0 …Run Code Online (Sandbox Code Playgroud)