所以我有这个课程:
class foo {
public:
foo() { };
void me1() const {
while(1) {
std::lock_guard<std::mutex> ldock(m);
std::cout << 0;
}
}
void me2() const {
while(1) {
std::lock_guard<std::mutex> ldock(m);
std::cout << 1;
}
}
private:
std::mutex m;
};
现在我想在两个不同的线程中运行这两个方法,我这样做:
int main() {
foo myfoo;
std::thread firstThread(&foo::me1, &myfoo);
std::thread secondThread(&foo::me2, &myfoo);
firstThread.detach();
secondThread.detach();
//while(1) { }
return 0;
}
我不想等待这两种方法中的任何一种方法完成,它们会同时运行直到主线程被杀死。
在主线程结束时是否可以使用某种无限循环? (如评论while(1) {}
)。
或者我应该打电话给某种sleep
函数吗?
答案 0 :(得分:3)
您需要在exit condition
和foo::me1()
中定义foo::me2()
。如果您不知道该怎么做,那
sleep(/*number of seconds you want your program to run*/ );
会做得很好。
如果你定义一个终止条款,那么强力就可以了 暴露像原子的东西:
class foo {
public:
std::atomic<int> me1done = false;
std::atomic<int> me2done = false;
foo() { };
void me1() {
while(/* need exit condition here*/) {
std::lock_guard<std::mutex> ldock(m);
std::cout << 0;
}
me1done = true;
}
void me2() {
while(/*need exit condition here*/) {
std::lock_guard<std::mutex> ldock(m);
std::cout << 1;
}
me2done = true;
}
private:
std::mutex m;
};
然后你可以通过每x秒轮询一次检查主。
int main(void)
{
// start your threads and detach
foo myfoo;
std::thread firstThread(&foo::me1, &myfoo);
std::thread secondThread(&foo::me2, &myfoo);
firstThread.detach();
secondThread.detach();
while( not (myfoo.me1done and myfoo.me2done ) )
{
sleep( /* some time */);
}
return 0;
}
如果您想要更详细,则必须使用condition variables。
答案 1 :(得分:2)
如果你想确定两个线程是否已经完成,那么在退出主线程之前,实际上不到detach()
线程而是join()
它们。也就是说,你将启动两个线程并且它们将同时运行,并且一旦开始,只需join()
。当然,这假定线程会终止。
有效地使用detach()
ed线程意味着您永远无法确定它是否已完成。这通常很少有用,我认为将detach()
添加到std::thread
是一个错误。但是,即使使用detach()
ed线程,您也可以识别何时在没有繁忙等待的情况下实现目标。为此,您需要设置适当的变量来指示完成或进度,并使其受std::mutex
保护。然后,wait()
上的主线程std::condition_variable
将在完成/进度更新时由相应线程获得notify_once()
,这将在合理的时间间隔内完成。一旦所有线程都表明它们已完成或已达到合适的目标,main()
线程就可以完成。
单独使用计时器通常不是一个好方法。线程之间的信令通常是优选的,并且倾向于创建响应更快的系统。您仍然可以使用wait()
的定时版本(例如,wait_until()
或wait_for()
),例如,在怀疑某个挂起或超时的线程时发出警告。
答案 2 :(得分:0)
空无限循环,因为while(1) { }
是UB。
在内部添加睡眠是可以的。
要无限运行foo::me1
/ foo::me2
,您还有其他几种选择:
int main()
{
foo myfoo;
std::thread firstThread(&foo::me1, &myfoo);
std::thread secondThread(&foo::me2, &myfoo);
firstThread.join(); // wait infinitely as it never ends.
secondThread.join(); // and so never reach
}
或者只是使用主线程来完成一项工作:
int main()
{
foo myfoo;
std::thread firstThread(&foo::me1, &myfoo);
myfoo.me2(); // work infinitely as it never ends.
firstThread.join(); // and so never reach
}