阻塞主线程等待它的子线程
block the main thread to wait for its child threads
所以我有这个 class:
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
函数吗?
您需要在 foo::me1()
和 foo::me2()
中定义 exit condition
。如果您不知道该怎么做,那
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 秒轮询一次来检查 main。
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。
如果你想确定这两个线程是否已经完成,你最好的选择实际上是 而不是 到 detach()
线程,而是 join()
它们在退出之前主线程。也就是说,您将启动两个线程,它们将同时 运行,一旦启动,您只需 join()
每个线程。当然,这是假设线程会终止。
有效地拥有一个 detach()
ed 线程意味着您永远无法确定它是否已完成。这通常很少有用,我认为将 detach()
添加到 std::thread
是一个错误。但是,即使使用 detach()
ed 线程,您 也可以 识别何时实现 objective 而无需忙等待。为此,您需要设置合适的变量来指示完成或进度,并让它们受到 std::mutex
的保护。然后主线程将在 std::condition_variable
上 wait()
,在 completion/progress 更新后由相应线程 notify_once()
ed,这将在合理的时间间隔内完成。一旦所有线程都表明它们已完成或已达到合适的 objective,main()
线程就可以完成。
单独使用计时器通常不是一个好的方法。线程之间的信号通常是可取的,并且往往会创建一个响应速度更快的系统。您仍然可以使用 wait()
的定时版本(即 wait_until()
或 wait_for()
),例如,在怀疑线程挂起或超时时发出警报。
空无限循环,因为 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
}
所以我有这个 class:
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
函数吗?
您需要在 foo::me1()
和 foo::me2()
中定义 exit condition
。如果您不知道该怎么做,那
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 秒轮询一次来检查 main。
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。
如果你想确定这两个线程是否已经完成,你最好的选择实际上是 而不是 到 detach()
线程,而是 join()
它们在退出之前主线程。也就是说,您将启动两个线程,它们将同时 运行,一旦启动,您只需 join()
每个线程。当然,这是假设线程会终止。
有效地拥有一个 detach()
ed 线程意味着您永远无法确定它是否已完成。这通常很少有用,我认为将 detach()
添加到 std::thread
是一个错误。但是,即使使用 detach()
ed 线程,您 也可以 识别何时实现 objective 而无需忙等待。为此,您需要设置合适的变量来指示完成或进度,并让它们受到 std::mutex
的保护。然后主线程将在 std::condition_variable
上 wait()
,在 completion/progress 更新后由相应线程 notify_once()
ed,这将在合理的时间间隔内完成。一旦所有线程都表明它们已完成或已达到合适的 objective,main()
线程就可以完成。
单独使用计时器通常不是一个好的方法。线程之间的信号通常是可取的,并且往往会创建一个响应速度更快的系统。您仍然可以使用 wait()
的定时版本(即 wait_until()
或 wait_for()
),例如,在怀疑线程挂起或超时时发出警报。
空无限循环,因为 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
}