繁体   English   中英

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

[英]std::thread when is thread executed?

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

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

线程是在我调用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(); }
};

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

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

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

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

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

操作系统很重要,但它相当普遍。 线程被安排执行。 当操作系统到处实际运行时,完全无法预测。 你可以在拥有多个内核的机器上“快速”获得不错的赔率,这在今天是普遍可用的。

thread :: join()只是确保线程完成执行。 永远不会真正编写这样的代码,启动一个线程然后等待它完成是完全没有意义的。 也可以直接执行线程的代码。 通过创建线程而不会影响操作系统的结果相同。

您无法知道您的线程将以何种顺序或核心运行。

一个posix线程基本上被linux视为一个与另一个共享其堆的进程。 内核将安排它们并决定使用哪个核心。 例如,查看生成的(受保护的)程序集,您将看不到任何“多核/多线程编程”,因为这是在内核级别完成的。

这就是为什么存在诸如连接之类的函数和诸如互斥锁/信号量之类的工件的原因。 照顾比赛条件和其他相关的东西。

线程是在我调用join()时执行还是在创建线程和调用join之间的某个时间运行?

在创建线程后执行(启动)线程,具体取决于可能需要一些时间的可用资源。 join()方法等待(阻塞),直到线程完成其工作。

一个建议:我不会将变量命名为Sync对象This ,令人困惑,因为存在this关键字。

您可以在Async::Inc()调用join()之后安全地删除std::thread对象,而且您不需要将引用存储为成员变量,它只在该函数中使用。

您还可以查看<atomic>标头, std::atomic<int>std::atomic_int

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM