我是多线程的新手。下面是我试图运行的示例代码。请原谅语法错误(如果有的话),因为我要记忆
下面的代码的问题是它立即终止,而它应该永远运行。我想知道为什么主要调用解构函数,即使有一个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
}
}
答案 0 :(得分:0)
第二个线程将在c.function1()调用时创建,但主线程继续运行。但是,你在desctuctor中有thread_ptr-&gt; join()会导致无限循环(取决于系统时序),如果你声明并使用myclass,就像在例1中一样,因为析构函数被称为主要出口。
主线程将在thread-&gt; 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()
答案 1 :(得分:0)
你的主要需要是这样的:
int main()
{
myclass Object;
Object.function1();
while(true){
}
// Or wait for a join by the thread...
return 0;
}
调用您对象的析构函数,因为当主终止时,Object
超出范围。
当一个进程退出/终止时,它的所有线程也是如此。确保处理不会终止的快速方法是在创建线程后添加while(true)
循环。
正如您的评论中所提到的,您希望在类中“封装”while循环。您可以像function1()
一样添加它:
void myclass::function1()
{
// some stuff
tr_ptr = thread_ptr(new boost::thread(&myclass::myfunction, this));
while(true){
// Do something
}
}
然而,它会“阻塞”你的主线程,首先失去了实现线程的大部分优势。