在地图中插入 thread::id 和 class 实例
Inserting thread::id and class instance in a map
我有一个class:
class IOWorker {
std::thread thread_;
boost::asio::io_service ios_;
boost::optional<boost::asio::io_service::work> work_;
Callback callback_;
// Map of thread::id and this class' instance
typedef std::map<std::thread::id, IOWorker *> IOWorkerThreadMap;
static IOWorkerThreadMap iOWorkerThreadMap;
public:
IOWorker(Callback cb);
~IOWorker();
std::thread::id getThreadId() {
return thread_.get_id();
}
// IO worker threads will call this to fetch their instance
static IOWorker* getIOWorkerInstance (void) {
auto it = iOWorkerThreadMap.find(std::this_thread::get_id());
if (it == iOWorkerThreadMap.end()) {
return nullptr;
}
return (it->second);
}
};
IOWorker::IOWorker (Callback cb) : callback_{cb}
{
work_ = boost::in_place(boost::ref(ios_));
thread_ = std::thread{[this] () {
ios_.run();
}
};
}
在主线程执行的函数中,我创建了这个 class 的 10 个实例并将它们插入映射中,其中 thread::id
是键,class
实例是值.
我正在从所有工作线程访问此地图,以通过在地图中查找它们的 thread::id
来获取它们各自的 class
实例。主线程也访问这些实例,以调用一些方法,post ios_ 上的作业等
void startIOWorkers (Callback cb)
{
for (int i = 0; i < 10; ++i) {
IOWorker *iow = new IOWorker{cb};
std::thread::id threadId = iow->getThreadId();
IOWorkerThreadMap.insert(std::make_pair(threadId, iow));
}
}
我的问题是针对以下行:
IOWorkerThreadMap.insert(std::make_pair(threadId, iow));
我的理解(可能是错误的!)是上面函数中的 iow
和 threadId
将在我将它们插入地图时被“复制”,并且它们的两个副本将存在。
我想避免这种情况,因此,我想知道在这种情况下拥有 thread::id
和 class
实例映射的更好方法是什么?
这似乎比实际情况要复杂得多。
如果看起来像这种情况,您只需要从 thread::this_thread
访问地图,该语言已经在 thread_local
中内置了 map<thread_id, T>
。
class IOWorker {
std::thread thread_;
boost::asio::io_service ios_;
boost::optional<boost::asio::io_service::work> work_;
Callback callback_;
static thread_local IOWorker* this_thread_worker_;
public:
IOWorker(Callback cb);
~IOWorker();
// IO worker threads will call this to fetch their instance
static IOWorker* getIOWorkerInstance (void) {
return this_thread_worker_;
}
};
IOWorker::IOWorker (Callback cb) : callback_{std::move(cb)}
{
work_ = boost::in_place(boost::ref(ios_));
thread_ = std::thread{[this] () {
this_thread_worker_ = this;
ios_.run();
};
}
std::vector<IOWorker> startIOWorkers(Callback cb)
{
std::vector<IOWorker> launched_workers;
launched_workers.reserve(10);
for (int i = 0; i < 10; ++i) {
launched_workers.emplace_back(cb);
}
return launched_workers;
}
我有一个class:
class IOWorker {
std::thread thread_;
boost::asio::io_service ios_;
boost::optional<boost::asio::io_service::work> work_;
Callback callback_;
// Map of thread::id and this class' instance
typedef std::map<std::thread::id, IOWorker *> IOWorkerThreadMap;
static IOWorkerThreadMap iOWorkerThreadMap;
public:
IOWorker(Callback cb);
~IOWorker();
std::thread::id getThreadId() {
return thread_.get_id();
}
// IO worker threads will call this to fetch their instance
static IOWorker* getIOWorkerInstance (void) {
auto it = iOWorkerThreadMap.find(std::this_thread::get_id());
if (it == iOWorkerThreadMap.end()) {
return nullptr;
}
return (it->second);
}
};
IOWorker::IOWorker (Callback cb) : callback_{cb}
{
work_ = boost::in_place(boost::ref(ios_));
thread_ = std::thread{[this] () {
ios_.run();
}
};
}
在主线程执行的函数中,我创建了这个 class 的 10 个实例并将它们插入映射中,其中 thread::id
是键,class
实例是值.
我正在从所有工作线程访问此地图,以通过在地图中查找它们的 thread::id
来获取它们各自的 class
实例。主线程也访问这些实例,以调用一些方法,post ios_ 上的作业等
void startIOWorkers (Callback cb)
{
for (int i = 0; i < 10; ++i) {
IOWorker *iow = new IOWorker{cb};
std::thread::id threadId = iow->getThreadId();
IOWorkerThreadMap.insert(std::make_pair(threadId, iow));
}
}
我的问题是针对以下行:
IOWorkerThreadMap.insert(std::make_pair(threadId, iow));
我的理解(可能是错误的!)是上面函数中的 iow
和 threadId
将在我将它们插入地图时被“复制”,并且它们的两个副本将存在。
我想避免这种情况,因此,我想知道在这种情况下拥有 thread::id
和 class
实例映射的更好方法是什么?
这似乎比实际情况要复杂得多。
如果看起来像这种情况,您只需要从 thread::this_thread
访问地图,该语言已经在 thread_local
中内置了 map<thread_id, T>
。
class IOWorker {
std::thread thread_;
boost::asio::io_service ios_;
boost::optional<boost::asio::io_service::work> work_;
Callback callback_;
static thread_local IOWorker* this_thread_worker_;
public:
IOWorker(Callback cb);
~IOWorker();
// IO worker threads will call this to fetch their instance
static IOWorker* getIOWorkerInstance (void) {
return this_thread_worker_;
}
};
IOWorker::IOWorker (Callback cb) : callback_{std::move(cb)}
{
work_ = boost::in_place(boost::ref(ios_));
thread_ = std::thread{[this] () {
this_thread_worker_ = this;
ios_.run();
};
}
std::vector<IOWorker> startIOWorkers(Callback cb)
{
std::vector<IOWorker> launched_workers;
launched_workers.reserve(10);
for (int i = 0; i < 10; ++i) {
launched_workers.emplace_back(cb);
}
return launched_workers;
}