【问题标题】:Initializing std::thread in ctor of movable class在可移动类的 ctor 中初始化 std::thread
【发布时间】:2012-03-05 13:21:13
【问题描述】:

我需要在类的 ctor 中初始化一个 std::thread。线程应该运行类本身的成员函数。在 ctor 中尝试初始化线程时,程序会尝试运行成员函数。 (实现了移动语义)。

Page::Page(Motion *_parent):
    parent(_parent)
{
    std::thread x(&Page::play,this);
    starter = std::move(x);
}

程序运行play() of this

编辑:我这样做:

void Page::start()
{
    std::thread x(&Page::play,this);
    x.join();
}

并且工作正常,但不知道是否可以...现在我正在使用std::bind,如果这是标准的做法,我将替换代码。

【问题讨论】:

  • 我不明白你的问题是什么。
  • @kukyakya:问题出在 ctor 的第一行,程序运行 this->play()
  • @Joachim:我想不通...
  • @SorushRabiee 但这有什么问题吗?很难理解你的问题。
  • @DavidSchwartz 我有一个成员函数play() 和一个std::thread starter 作为类的成员。我想用实例的play 初始化那个线程。

标签: c++ multithreading c++11 std


【解决方案1】:

std::thread 的构造函数立即自动启动线程,然后新线程调用提供的函数,所以

std::thread x(&Page::play,this);

在新线程上自动调用this->play()

这与某些线程库(例如 .Net)不同,在这些线程库中,您必须通过调用 Start() 成员函数来显式启动线程。 std::thread 没有“延迟启动”功能。

如果您不希望线程在调用其他函数之前实际启动,请不要在构造函数中初始化 std::thread 对象,而是在您的 start() 函数中进行初始化,如您所示。

如果您在线程对象上调用join(),那么您的代码将在调用join() 时等待线程完成。因此,如果您在构造线程对象后立即加入连接,如您的示例 start() 函数,那么您最好直接调用 play(),因为 start() 在线程完成之前不会返回。

您不需要 std::bindstd::thread --- 线程构造函数会自动处理绑定。

【讨论】:

  • “std::thread 没有“延迟启动”功能。您实际上可以使用 yield 来控制线程何时启动。
  • Yield 不提供对线程何时启动的任何控制。您可以使用std::promisestd::futurestd::condition_variable 之类的信号机制,甚至std::atomic<bool> 标志来延迟运行新线程上的“重要”部分代码,但您无法控制当线程本身启动时。
  • 不直接但间接你可以例如:cplusplus.com/reference/thread/this_thread/yield
  • 如果您检查了代码,它实际上是在 std::atomic<bool> 标志上的旋转等待。 yield 调用只是为了避免在旋转时占用处理器。
【解决方案2】:

这样的事情怎么样:

#include <iostream>
#include <thread>
#include <functional>

struct Foo
{
    Foo()
        : thread(std::bind(Foo::bar, this))        
        { }

    ~Foo() 
        { thread.join(); }

    static void bar(Foo *foo)
        { }

    std::thread thread;
};

int main()
{
    Foo foo;
}

【讨论】:

    猜你喜欢
    • 2016-10-05
    • 2012-02-07
    • 2022-09-21
    • 2015-02-11
    • 2015-05-22
    • 2017-05-21
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多