我正在尝试在C ++ 11的std::thread
之上构建一个线程安全层,其中每个对象都分配给一个拥有的线程,并且某些调用在错误的线程上使用时可能会引发严重错误。 。拥有线程是唯一可以将对象转移到另一个线程的线程。
我一切正常, 除外,我找不到在线程实际运行之前获取线程thread::id
的方法。而且我需要在将新线程的ID附加到该对象之前,将其移交。
如果我使用
std::thread newThread( [theObject]()
{
// use theObject here.
} );
最早可以获取线程ID的地方是在定义线程对象之后,此时线程已经在运行。
我看到std::thread
有一个默认的构造函数,但是我看不到给它一个以后在线程上运行的函数的方法。
是否可以在线程上执行两步构造,或者在创建时控制线程的ID?
答案 0 :(得分:6)
您可以考虑让线程执行的功能在起飞前进行一些初始设置,而不是在开始运行之前获取线程的ID。例如,您可以执行以下操作:
bool isReady = false;
bool wasReceived = false;
std::mutex mutex;
std::condition_variable condition;
std::thread newThread([theObject, &isReady, &mutex, &condition] {
/* Wait until we've been cleared to go. */
std::unique_lock<std::mutex> lock(isReady);
condition.wait(lock, [&isReady] { return isReady; });
/* Signal that we're done. */
wasReceived = true;
lock.unlock();
condition.notify_one();
/* Put code here to do whatever it is that the thread should do. */
});
/* Read the thread's ID. It's currently waiting for us. */
auto id = newThread.get_id();
/* Tell the thread that we're ready for it. */
std::unique_lock<std::mutex> lock(mutex);
isReady = true;
condition.notify_one();
/* Wait until the thread has confirmed that it's ready. */
condition.wait(lock, [&] { return wasReceived; });
这将创建线程并将其放置并等待,直到创建者有机会读取其ID。一旦发生这种情况,创建者便会等待,直到线程确认已准备就绪,然后您就可以根据需要使用线程ID了。
当心上面代码中的错误-完全未经测试。 :-)
答案 1 :(得分:5)
否-创建线程后,它将立即开始运行。如果要在执行任何操作之前先获取其ID,则可能要创建一个小包装器,在该包装器中将线程(例如)传递给CV和一个队列,在该线程中存放输出。
然后,当线程启动时,它检索自己的ID,将其存储在输出队列中,然后等待CV。父母取回ID并准备好让孩子开始做某事时,它会向简历发出信号,然后就消失了。
答案 2 :(得分:3)
通过传递唯一的std :: promise参数来启动每个处于非活动状态的线程,首先获取线程ID(为此目的,线程ID用作通过引用参数传递的对象),然后让其等待线程设置诺言经理。这也将消除使用条件变量的麻烦。
已编辑代码段
class smart_thread {
public:
smart_thread(std::function<void(void)> task)
{
thread_ = std::thread([=]() {
id_ = std::this_thread::get_id();
// wait here till activated
future_.get();
if(active_) task();
});
}
void activate() {
promise_.set_value();
active_ = true;
}
~smart_thread() {
if(!active_) promise_.set_value();
thread_.join();
}
private:
std::thread::id id_;
std::atomic<bool> active_ = false;
std::thread thread_;
std::promise<void> promise_;
std::future<void> future_ = promise_.get_future();
};
void main()
{
auto task = []() { std::cout << "Hello World\n"; };
smart_thread thread(task); // start thread inactive mode
thread.activate(); // activate thread
}
答案 3 :(得分:0)
是否可以创建一个模板类,以Data,Class
[ 0.02713807 0.01802697 0.01690036 0.01501216 0.01466412 0.01638859
0.0210163 0.02658022 0.03664452 0.05064286 0.06027664 0.06431134
0.04303673 0.03247764 0.02293602 0.01847688 0.0174582 0.01860664
0.02576164 0.02296149 0.0582211 0.37246149]
,[fail]
[ 0.03623561 0.05211099 0.02469929 0.0134991 0.01029103 0.00880611
0.00898548 0.00870684 0.0117465 0.01962223 0.03895351 0.01956952
0.00972828 0.00704872 0.00656471 0.00689743 0.00854528 0.01128713
0.02119957 0.05047751 0.05028719 0.57473797]
,[fail]
[ 0.04293871 0.0292026 0.02329546 0.01473342 0.01127858 0.0107691
0.01203 0.01478981 0.02045828 0.03043333 0.03817313 0.03602836
0.02284631 0.014719 0.00999932 0.00857384 0.00940592 0.0143105
0.02862624 0.03424553 0.05910089 0.51404167]
,[pass]
[ 0.0274558 0.02260355 0.0120938 0.00766592 0.00623965 0.00700311
0.0105109 0.01435633 0.0228327 0.03671535 0.0509835 0.06406992
0.03382424 0.02283531 0.01455474 0.01196762 0.01238184 0.01560769
0.02885654 0.03067498 0.07337675 0.47338975]
,[pass]
[ 0.04557506 0.03065541 0.02441537 0.0145579 0.0114853 0.01115224
0.01330945 0.01539609 0.01776064 0.0216626 0.02218757 0.02153467
0.01548431 0.01295433 0.01045522 0.0100229 0.01051257 0.01454908
0.02735121 0.03250603 0.05923302 0.55723903]
,[pass]
的形式接受线程例程。如果需要传递其他参数,则可以使用匿名闭包轻松完成此操作。
std::function<void(T *object)>
当心上面代码中的错误-完全未经测试。 :-):-)