如何解决在地图中插入 thread::id 和 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();
}
};
}
在一个由主线程执行的函数中,我创建了这个类的 10 个实例并将它们插入到映射中,其中 thread::id
是键,class
实例是值。
我正在从所有工作线程访问此映射,以通过在映射中查找它们的 class
来获取它们各自的 thread::id
实例。主线程也访问这些实例,调用一些方法,在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
访问地图,那么该语言已经内置了 map<thread_id,T>
:thread_local
。
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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。