std :: thread:如何在类体中声明一个线程作为正常成员? [英] std::thread : how to declare a thread in class body as a normal member?

查看:263
本文介绍了std :: thread:如何在类体中声明一个线程作为正常成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为 Page 对象的每个实例都有一个线程。在某一时刻只有其中一个可以执行(简单地检查指向当前正在运行的线程的指针是否可以连接。)

 页面:public std :: vector< Step> 
{
// ....
void play();
void start(); //检查是否没有其他线程正在运行。如果有一个正在运行的线程,则返回。 else join starter
std :: thread starter; // std :: thread running this-> play()
static std :: thread * current; //指向当前正在运行的线程的指针
// ...
};

我想要启动 starter 线程页面对象。例如像这样:

 页面x,y,z; 
//做一些初始化页面的东西。
x.start();
//做一些其他工作
y.start(); //如果x完成,开始y否则不做任何操作
//做一些其他冗长的工作
z.start(); //如果x和y不在运行,则启动z

我不能声明作为 Page 的成员启动。我发现这是因为事实 std :: thread s只能在声明时初始化。 (或类似的东西,因为它不可能复制线程)

  void x()
{
}
// ...
std :: thread t(x); // this is ok
std :: thread r; //这是错的,但我需要这个!
r = std :: thread(this-> y); // no hope
r = std :: thread(y); // this is wrong too


解决方案

到要通过使用成员初始化器列表运行的函数。例如,考虑的此构造函数:

  b $ b public:
Page(); //例如

private:
std :: thread toRun;
};

Page :: page():toRun(/ * function to run * /){
/ * ... * /
}
Page
构造函数中的初始化列表来初始化<$ c>

$ c> toRun 到应该运行的函数。这样, toRun 就像您声明为局部变量一样初始化

  std :: string toRun(/ * function to run * /); 

也就是说,我认为你必须在代码中解决两个主要问题。首先,您应该继承 std :: vector 或任何标准集合类。这些类不具有标记为 virtual 的析构函数,这意味着如果您尝试处理您的作为 std :: vector 。相反,可以考虑将 Page 保存为 std :: vector 作为直接子对象。另外,你不应该暴露类的 std :: thread 成员。数据成员通常应该 private 以增加封装,使以后更容易修改类,并防止人们破坏所有类的不变式。



希望这有助于!


I want to have a thread for each instance of Page object. At a time only one of them can execute (simply checks if pointer to current running thread is joinable or not..)

class Page : public std::vector<Step>
{
    // ....
    void play();
    void start(); // check if no other thread is running. if there is a running thread, return. else join starter
    std::thread starter; // std::thread running this->play()
    static std::thread* current; // pointer to current running thread
    // ...
};

I want to be able to fire-up starter threads of Page objects. for example like this:

Page x , y , z;
// do some stuff for initialize pages..
x.start();
// do some other work
y.start(); // if x is finished, start y otherwise do nothing
// do some other lengthy work
z.start(); // if x and y are not running, start z

I can't manage to declare started as a member of Page. I found that it's because of the fact std::threads can only initialized at declaration time. (or something like that, cause it's not possible to copy a thread)

void x()
{
}
//...
std::thread t(x);          // this is ok
std::thread r;             // this is wrong, but I need this !
r = std::thread(this->y);  // no hope
r = std::thread(y);        // this is wrong too

解决方案

You can initialize the thread to the function to run by using a member initializer list. For example, consider this constructor for Page:

class Page {
public:
    Page(); // For example

private:
    std::thread toRun;
};

Page::Page() : toRun(/* function to run */) {
    /* ... */
}

Notice how we use the initialization list inside the Page constructor to initialize toRun to the function that ought to be run. This way, toRun is initialized as if you had declared it as a local variable

std::string toRun(/* function to run */);

That said, there are two major problems I think that you must address in your code. First, you should not inherit from std::vector or any of the standard collections classes. Those classes don't have their destructors marked virtual, which means that you can easily invoke undefined behavior if you try to treat your Page as a std::vector. Instead, consider making Page hold a std::vector as a direct subobject. Also, you should not expose the std::thread member of the class. Data members should, as a general rule, be private to increase encapsulation, make it easier to modify the class in the future, and prevent people from breaking all of your class's invariants.

Hope this helps!

这篇关于std :: thread:如何在类体中声明一个线程作为正常成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆