问题描述
我想为 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 * /){
/ * ... * /
}
$ c请注意我们如何使用Page
构造函数中的初始化列表来初始化<$ c> $ c> toRuntoRun
就像您声明为局部变量一样初始化std :: string toRun(/ * function to run * /);
也就是说,我认为你必须在代码中解决两个主要问题。首先,您应该不继承
std :: vector
或任何标准集合类。这些类不具有标记为virtual
的析构函数,这意味着如果您尝试处理您的页$ c,您可以轻松地调用未定义的行为$ c>作为
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 ofPage
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 ofPage
. I found that it's because of the factstd::thread
s 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 initializetoRun
to the function that ought to be run. This way,toRun
is initialized as if you had declared it as a local variablestd::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 markedvirtual
, which means that you can easily invoke undefined behavior if you try to treat yourPage
as astd::vector
. Instead, consider makingPage
hold astd::vector
as a direct subobject. Also, you should not expose thestd::thread
member of the class. Data members should, as a general rule, beprivate
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:如何在类体中声明一个线程作为正常成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!