2012-02-14 45 views
0

我需要在类的ctor中初始化std :: thread。线程应该运行类本身的成员函数。在尝试初始化线程时,程序试图运行成员函数。 (移动语义被执行)。初始化可移动类的ctor中的std :: thread

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

程序运行的thisplay()

编辑:我这样做:

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

而且工作正常,但不知道是否确定或不...现在我玩std::bind如果它这样做的标准方式,我将会替换代码。

+1

我不明白你的问题是什么。 – kukyakya 2012-02-14 06:14:15

+0

@kukyakya:问题出在ctor的第一行,程序运行'this-> play()'。 – 2012-02-14 06:18:39

+0

@Joachim:我想不出来...... – 2012-02-14 06:56:33

回答

2

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 ---线程构造函数自动处理绑定。

+0

“std :: thread没有”延迟启动“工具。实际上,您可以使用yield来控制线程何时启动。 – user18490 2013-08-11 17:47:13

+0

Yield在线程启动时不提供任何控制权。你可以使用'std :: promise'和'std :: future',或者'std :: condition_variable'等信号机制,或者甚至是一个'std :: atomic '标志来延迟新线程上的代码已经运行,但您无法控制线程本身何时启动。 – 2013-08-12 08:00:42

+0

没有直接但间接你可以举例:http://www.cplusplus。com/reference/thread/this_thread/yield/ – user18490 2013-08-14 13:21:26

1

怎么是这样的:

#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; 
}