gpt4 book ai didi

带有 thread_local 的 C++ Schwarz 计数器

转载 作者:行者123 更新时间:2023-11-30 05:07:42 26 4
gpt4 key购买 nike

我可以使用Schwarz counter (aka Nifty counter)吗?成语,用thread_local? (假设我将所有 static 替换为 thread_local)

我需要这个(java jni 线程的助手):

class ThisThread{
JNIEnv* jni_env{nullptr};
public:
JNIEnv* getEnv(){
if (!jni_env){
// Attach thread
java_vm->GetEnv((void**)&jni_env, JNI_VERSION);
java_vm->AttachCurrentThread(&jni_env, NULL);
}

return jni_env;
}

~ThisThread(){
if (!jni_env) return;
// Deattach thread
java_vm->DetachCurrentThread();
}
};

static thread_local ThisThread this_thread;

在每个线程中首先构造,最后析构。我可以从其他静态或 thread_local 对象的析构函数/构造函数调用 this_thread->getEnv()

更新

https://stackoverflow.com/a/30200992 - 这里,标准说 thread_local 析构函数调用了 BEFORE static,我需要这个在之后。

最佳答案

我认为最好的解决方案是像往常一样实现 schwartz 计数器,但是根据 thread_local static Impl 实现 ThisThread 类.

带有输出的完整示例:

// header file
#include <memory>
#include <mutex>
#include <iostream>
#include <thread>

std::mutex emit_mutex;

template<class...Ts>
void emit(Ts&&...ts)
{
auto action = [](auto&&x) { std::cout << x; };
auto lock = std::unique_lock<std::mutex>(emit_mutex);

using expand = int[];
expand{ 0,
(action(std::forward<Ts>(ts)), 0)...
};
}


struct ThisThread
{
struct Impl
{
Impl()
{
emit("ThisThread created on thread ", std::this_thread::get_id(), '\n');
}
~Impl()
{
emit("ThisThread destroyed on thread ", std::this_thread::get_id(), '\n');
}
void foo()
{
emit("foo on thread ", std::this_thread::get_id(), '\n');
}
};

decltype(auto) foo() { return get_impl().foo(); }

private:
static Impl& get_impl() { return impl_; }
static thread_local Impl impl_;
};

struct ThisThreadInit
{

ThisThreadInit();
~ThisThreadInit();

static int initialised;
};

extern ThisThread& thisThread;
static ThisThreadInit thisThreadInit;



// cppfile

static std::aligned_storage_t<sizeof(ThisThread), alignof(ThisThread)> storage;
ThisThread& thisThread = *reinterpret_cast<ThisThread*>(std::addressof(storage));
int ThisThreadInit::initialised;
thread_local ThisThread::Impl ThisThread::impl_;

ThisThreadInit::ThisThreadInit()
{
if (0 == initialised++)
{
new (std::addressof(storage)) ThisThread ();
}
}

ThisThreadInit::~ThisThreadInit()
{
if (0 == --initialised)
{
thisThread.~ThisThread();
}
}


// now use the object

#include <thread>

int main()
{
thisThread.foo();

auto t = std::thread([]{ thisThread.foo(); });
t.join();
}

示例输出:

ThisThread created on thread 140475785611072
foo on thread 140475785611072
ThisThread created on thread 140475768067840
foo on thread 140475768067840
ThisThread destroyed on thread 140475768067840
ThisThread destroyed on thread 140475785611072

关于带有 thread_local 的 C++ Schwarz 计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47202217/

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