3

我很好奇以下代码的准确性

for(int i=0 ; i<5 ; i++)
{
SomeClass* ptrinst = new SomeClass()
boost::thread t(  boost::bind (&SomeClass::SomeMethod,ptrinst));
......
}

当 t 超出范围时,正在运行的线程会发生什么?

4

1 回答 1

2

由于主线程不调用t.join(),主线程将继续运行其循环,产生额外的线程,然后继续前进。所以答案是,在您当前的编码下,子线程不会与您的父线程交互(至少不会直接)。

另请注意,该类是一个奇怪的野兽 - 当您超出范围thread时发生的唯一事情是,您的主线程不再有可以调用的句柄。它超出父线程范围的事实对子线程的影响为零。一旦您通过实例化子线程来生成子线程,子线程本质上就与父线程解耦(好吧,在父线程中可见的全局/动态分配的内存对子线程也是可见的,但是如果您需要互斥体,则需要修改/改变这些全局变量)。正如我稍后在帖子中提到的,您需要对线程上下文中的内存可见性和所有权有深入的了解。只是在这里阅读我的评论可能对您没有帮助。t.join()

如果您希望主线程等待子线程完成,则需要将这些线程存储在std::vector<boost::thread> v;循环外部,然后在第二个循环中调用join所有这些实例。

您当前的代码看起来有点可疑,因为您正在通过 bind 调用实例方法 - 这很好,但我通常不希望调用该实例方法,delete this;这意味着它由父线程来清理(父线程不应该清理直到子线程完成)。但是,如果没有某种线程同步,它就无法在正确的时间进行清理。因此,几乎可以确定内存泄漏或某种令人讨厌的竞争条件(假设您将 adelete ptrinst;放在...主线程的一部分中以尝试清理。如果没有某种同步,您可能会在子线程之前删除指针已完成使用它)。

此外,您可能希望使用std::threadstd::bind代替 boost 版本。

最后一点:我怀疑您仍在尝试使用线程。如果这是真的,那么在您尝试修复此代码之前,阅读并使用更简单的示例进行更多实验可能是一个好主意。否则,您可能会让自己陷入一个痛苦的世界(调试地狱,包括竞争条件、奇怪的内存同步问题等......)。

尝试更深入地了解内存和线程发生的情况:哪些内存对哪些线程可见,哪些内存可以共享和不可以共享。

于 2013-06-16T08:54:47.917 回答