我们有时候会有些不规范的编程习惯,如,在构造函数中开启detach分离线程
,或者在构造函数中写一个初始化函数,在这个初始化函数中开启detach分离线程
。这样做会有意想不到的程序崩溃问题,而且还不好排查。因为你所有的语法和逻辑都没有任何问题。
这种问题一般都是你的线程中调用了其他对象,但是那个对象却可能还没有初始化,没有初始化你就调用别人,肯定是会报错的。
我见到的是一个多继承的例子。
// Test继承A和B
class Test :A, B{
// Test的构造函数初始化,a(args)和b(args)分别是对类A和类B进行初始化
Test() : a(args), b(args){...}
private:
A a;
B b;
};
在A的构造函数中开了detach线程
,该线程中调用了B
。
但是程序崩溃了,程序报错信息告诉了你,是在调用B
的位置报了段错误
(也可能只会在调用B
的外层函数报段错误
)。你自己琢磨,逻辑并没有任何问题啊,为什么报错?问题就在一个小点上,你如果没有注意到两个类构造的先后顺序,可能就会不知所措:
我们看到, Test() : a(args), b(args){}
是先初始化A
,然后再初始化B
。A
的构造函数中就开启了detach线程
,在线程中调用B
时,B
还没有被初始化,程序肯定就会崩溃了。