std :: thread什么时候执行线程?

Che*_*tpp 3 c++ multithreading

我已经浏览了一些线程教程,但我很好奇一件事.

std::thread Child([](){ std::cout << "When am I executed?" << std::endl << std::endl; });

//Some other code

Child.join();

//I'm guessing now my thread would be running
Run Code Online (Sandbox Code Playgroud)

线程是在我调用时执行join()还是在创建线程和调用join之间的某个时间运行?如果在join()调用时执行它,只是为了检查我的理解,它告诉执行的部分,你的程序继续在主线程上,最终子线程在主线程正在使用的相同内存上做了一些工作?

如果我想为泛型类创建一个包装器,我会想做类似下面的事情,但我似乎无法完全弄明白.我对在内存方面管理线程很困惑.

class Sync {
private:
    int val;

public:
    Sync() : val(0) {}
    void Inc() {val++}
    int Value() { return val; }
};

class Async {
private:
    Sync Foo;
    std::mutex mtx;
    std::vector<std::thread*> Children;
public:
    //I would need a new thread each time I called Inc
    void Inc() { 
        Children.push_back(new std::thread([&]() {
            mtx.lock();
            Foo.Inc();
            mtx.unlock();
        }));


    }
    //But how do I know when it is safe to delete Child?  
    int Value() { 
        for(auto& thds : Children) {
            thds->join();
            delete thds; 
        }
        Children.clear();
        return Foo.Value(); }
};
Run Code Online (Sandbox Code Playgroud)

我正在考虑一个合适的位置可能在线程函数的末尾,因为不再需要Child但是如果你试图从内部破坏线程会发生什么?我猜这听起来不是一个坏主意.我怎么知道什么时候可以删除我的线程?有更好的方法吗?

修改上面的代码以反映下面的建议.

我现在意识到教程正在讨论关于抛出异常的内容,所以我应该使用互斥锁而不是mtx.lock()我想.

Mat*_*son 6

目的join是基本上等待线程完成.所以一旦Child->join();返回,你的线程就完成了.当然,您也可以Child->join()在析构函数中执行[或者在某些其他方面,确保在某些时候调用它].

请注意,线程将在实际创建的时间和连接结束之间的某个时刻开始运行.无法确定何时会发生这种情况.如果系统上已经运行了很多线程,则时间将在所有线程之间分配,并且您的线程可能无法运行几秒钟.另一方面,如果有一个CPU坐在那里"弄乱它的手指",它可能很可能在主线程离开new std::thread(...) 构造之前启动[因为std::thread在线程被正确创建之前不会返回,并且一些数据是存储在线程对象中,因此线程很可能在您到达时完成Child->join().如果不知道系统处于什么状态,就无法确定这些选项中的哪一个.

  • 是的,我刚刚编辑了答案,以澄清线程可能在您完成创建之前或之后的某个时刻开始.这完全取决于系统中有多少CPU /核心以及系统中的总体负载. (2认同)

Han*_*ant 5

操作系统很重要,但它相当通用。线程被安排执行。操作系统何时真正开始运行是完全不可预测的。在当今普遍可用的多核机器上,您将有很大的机会“快速”运行。

thread::join() 只是确保线程完成执行。你永远不会真正编写这样的代码,启动一个线程然后等待它完成是完全没有意义的。不妨直接执行线程的代码。相同的结果,不会因创建线程而使操作系统陷入困境。