main 终止具有无限循环的线程

main terminating a thread with infinite loop

本文关键字:线程 无限循环 终止 main      更新时间:2023-10-16

我对多线程很陌生。下面是我尝试运行的示例代码。请原谅语法错误(如果有的话),因为我是凭记忆。
下面代码的问题在于它会立即终止,而它应该永远运行。我想知道为什么主调用解构函数,即使有一个while (true)语句。

没有其他类,因此不是由于与其他类的交互。主要唯一要做的就是创建一个 myclass 类型的对象,并在下面调用 function1()。

int main()
{
myclass Object;
Object.function1();
return 0;
}
/**** new file   ******/
typedef boost::shared_ptr<boost::thread> thread_pointer;
class myclass
{
public:
// some stuff
void function1();
private:
// some stuff
void myfunction();
thread_pointer tr_ptr;  
};
~myclass() {
tr_ptr->join();
}
void myclass::function1()
{
// some stuff   
tr_ptr = thread_ptr(new boost::thread(&myclass::myfunction, this));  
}
void myclass::myfunction()
{
// some stuff
while(true){
// some stuff
} 
}

第二个线程将在 c.function1() 调用时创建,但随后主线程继续运行。 但是,在 desctuctor 中确实有 thread_ptr->join(),如果您像示例 1 中那样声明和使用 myclass,这将导致无限循环(取决于系统时间),因为析构函数被称为主出口。

主线程将在 thread->join() 上阻塞,直到子线程退出。 因此,例如 1,当执行的主线程离开定义 c 的作用域时,将调用析构函数,主线程将调用 join(),在那里它将等待子线程退出,并且由于子线程永远不会退出,主线程将永远阻塞。

示例 1:

int main(int argc,char *argv[])
{
myclass c;
c.function1();
}

但是,如果您像这样声明和使用它:

示例 2:

int main(int argc,char *argv[])
{
myclass *c = new myclass();
c->function1();
}

然后,由于通过 new 创建的对象必须显式销毁,因此不会调用析构函数,并且程序将立即退出,因为未调用 join()。

如果进一步将其更改为以下内容:

例3:

int main(int argc,char *argv[])
{
myclass *c = new myclass();
c->function1();
delete c;
}

你再次得到一个无限循环,因为再次调用析构函数将导致主线程调用 join()

你的主要内容需要像这样:

int main()
{
myclass Object;
Object.function1();
while(true){
}
// Or wait for a join by the thread...
return 0;
}

调用对象的析构函数是因为当 main 终止时,Object将超出范围。

线程的生命与它的调用进程相关联

当进程退出/终止时,它的所有线程也会退出/终止。确保进程不会终止的一种快速方法是在创建线程后添加while(true)循环。

如您的评论中所述,您希望在类中"封装"while循环。您可以像这样将其添加到function1()中:

void myclass::function1()
{
// some stuff   
tr_ptr = thread_ptr(new boost::thread(&myclass::myfunction, this));  

while(true){
// Do something
} 
}

但是,它会"阻塞"您的主线程,首先失去实现线程的大部分优势。