Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多个线程可以加入同一个boost::thread吗?_C++_Multithreading_Boost - Fatal编程技术网

C++ 多个线程可以加入同一个boost::thread吗?

C++ 多个线程可以加入同一个boost::thread吗?,c++,multithreading,boost,C++,Multithreading,Boost,如果多个线程尝试加入同一线程,则具有未定义的行为: 如果多个线程同时尝试与同一线程连接, 结果未定义 对s来说也是这样吗?文档中似乎没有指定这一点 如果它是未定义的,那么多个线程等待一个线程完成的干净方式是什么 如果它是未定义的,那么多个线程等待一个线程完成的干净方式是什么 干净的方法是让一个线程通知其他线程它已经完成。打包的_任务包含一个可以等待的未来,在这里可以帮助我们 这里有一种方法。我已经使用了std::thread和std::packaged_任务,但是您也可以使用boost等价物 #

如果多个线程尝试加入同一线程,则具有未定义的行为:

如果多个线程同时尝试与同一线程连接, 结果未定义

对s来说也是这样吗?文档中似乎没有指定这一点

如果它是未定义的,那么多个线程等待一个线程完成的干净方式是什么

如果它是未定义的,那么多个线程等待一个线程完成的干净方式是什么

干净的方法是让一个线程通知其他线程它已经完成。
打包的_任务
包含一个可以等待的
未来
,在这里可以帮助我们

这里有一种方法。我已经使用了std::thread和std::packaged_任务,但是您也可以使用boost等价物

#include <thread>
#include <mutex>
#include <future>
#include <vector>
#include <iostream>

void emit(const char* msg) {
    static std::mutex m;
    std::lock_guard<std::mutex> l(m);
    std::cout << msg << std::endl;
    std::cout.flush();
}

int main()
{
    using namespace std;

    auto one_task = std::packaged_task<void()>([]{
        emit("waiting...");
        std::this_thread::sleep_for(std::chrono::microseconds(500));
        emit("wait over!");
    });

    // note: convert future to a shared_future so we can pass it
    // to two subordinate threads simultaneously
    auto one_done = std::shared_future<void>(one_task.get_future());
    auto one = std::thread(std::move(one_task));

    std::vector<std::thread> many;
    many.emplace_back([one_done] {
        one_done.wait();
        // do my thing here
        emit("starting thread 1");
    });

    many.emplace_back([one_done] {
        one_done.wait();
        // do my thing here
        emit("starting thread 2");
    });

    one.join();
    for (auto& t : many) {
        t.join();
    }

    cout << "Hello, World" << endl;
    return 0;
}

我最终使用了一个
boost::condition\u变量
。。。大致:

class thread_wrapper {
    boost::mutex mutex;
    boost::condition_variable thread_done_condition;
    bool thread_done = false;

    void the_func() {
        // ...
        // end of the thread
        {  
            boost:unique_lock<boost::mutex> lock(mutex);
            thread_done = true;
        }
        thread_done_condition.notify_all();
    }

    void wait_until_done() {
        boost::unique_lock<boost::mutex> lock(mutex);
        thread_done_condition.wait(lock, [this]{ return thread_done; });
    }
}
类线程\u包装器{
互斥互斥;
boost::条件\可变线程\完成\条件;
bool thread_done=false;
使_func()无效{
// ...
//线头
{  
boost:唯一的锁(互斥锁);
thread_done=true;
}
线程_done_条件。通知_all();
}
无效等待直到完成(){
boost::唯一的锁(互斥锁);
线程_done_condition.wait(锁定,[this]{返回线程_done;});
}
}

然后,多个呼叫者可以安全地呼叫
等待,\u直到完成()

现在我突然想到,类似以下的东西也会奏效:

class thread_wrapper {
public:
    thread_wrapper() : thread([this]() { this->the_func(); }) { }

    void wait_until_done() {
        boost::unique_lock<boost::mutex> lock(join_mutex);
        thread.join();
    }

private:
    void the_func() {
        // ...
    }

    boost::mutex join_mutex;
    boost::thread thread;
}
类线程\u包装器{
公众:
thread_wrapper():线程([this](){this->the_func();}){}
无效等待直到完成(){
boost::unique_lock锁(join_mutex);
thread.join();
}
私人:
使_func()无效{
// ...
}
互斥体加入互斥体;
boost::线程;
}

HMM,有趣的是,在我能阅读的N429 6C++标准草案中没有提到。我会说这是UB和/或“不要这样做”的行为。:)其他线程可以测试一个线程是否为
joinable()
,或者关闭线程可以使用
condition\u variable
来表示其所有工作都已完成(即使它可能仍在运行)@wilx,
std::thread::join()
是一个非常量函数,因此并发调用它是一种数据竞争,即未定义的行为。除非另有规定,否则该规则适用于所有标准库类型。@Tas,如果两个线程同时调用
joinable()
,那么如何停止这两个线程,然后尝试调用
join()
?即使只有一个线程调用
join()
,如果没有某种同步,
join()
调用也会与另一个线程中的
joinable()
调用冲突,从而导致数据争用,即未定义的行为。
class thread_wrapper {
public:
    thread_wrapper() : thread([this]() { this->the_func(); }) { }

    void wait_until_done() {
        boost::unique_lock<boost::mutex> lock(join_mutex);
        thread.join();
    }

private:
    void the_func() {
        // ...
    }

    boost::mutex join_mutex;
    boost::thread thread;
}