1、多线程编程中应该注意的问题1. 线程的优先级多线程编程中要注意协调好各个线程的优先级。一般来说,控制线程的优先级要高于Worker 线程。这样做,可以保证 Client(最终用户或者其他模块)尽快得到响应。当控制线程是与最终用户交互的界面线程时更应如此,如果界面线程优先级较低,界面可能较长时间没有反应,用户很可能会怀疑命令是不是还没有开始执行。下面两张图给出了控制线程优先级不同对 Client 造成不同响应时间的对比。用户 控制线程请求通知 W o r k e r 处理请求W o r k e r 线程工作中 工作中 请求正在处理通知用户请求处理完毕线程切换线程切换线程切换响应时间控制线程低优先
2、级 , W o r k e r 线程高优先级Fig 1.1 控制线程优先级低,对用户响应时间较长用户 控制线程请求通知 W o r k e r 处理请求W o r k e r 线程工作中 工作中 请求正在处理通知用户请求处理完毕线程切换线程切换线程切换响应时间控制线程高优先级 , W o r k e r 线程低优先级Fig 1.2 控制线程优先级高,对用户响应时间较短2. 防止栈溢出这个问题不只存在在多线程编程中。防止栈溢出可以参考下面几条建议:1) 不在函数体内定义特别大的栈变量,必须要定义的时候,可以使用 new 在堆上分配。2) 传递参数时,大的参数(如结构体,类)使用按指针传递,小的参
3、数(如基本数据类型)使用按值传递。P a r a m e t e r C o p y o f P a r a m e t e r1 . 分配和参数大小相同的空间 。参数 - 大的对象堆栈压栈M e m o r y2 . 调用拷贝构造函数构造一个对象 。3 . 将构造的对象压入堆栈 。Fig 2.1 大对象作为参数时,按值传递的过程P a r a m e t e rC o p y o f Unlock();Lock();Unlock();这是因为,如果第一次 Unlock 和第二次 Lock 之间,成员变量的值可能发生了变化,而如果 Func 函数恰好在两次 Lock 的时候都用到了那个发生了变
4、化的成员变量,那么错误就有可能发生了。模块线程 模块线程 模 块外部模块 外部模块 U p d a t e m _ p I R e a l 3 D . l I n d e xL o c k m _ p I R e a l 3 Dl I n d e x = m _ p I R e a l 3 D . l I n d e xU n l o c k m _ p I R e a l 3 DL o c k m _ p I R e a l 3 Dm _ p I R e a l 3 D . l I n d e x = l I n d e xU n l o c k m _ p I R e a l 3 DU p
5、 d a t e m _ p I R e a l 3 DL o c k m _ p I R e a l 3 Dm _ p I R e a l 3 D . R e a l e a s e ( )m _ p I R e a l 3 D = n e w C R e a l 3 D ( )U n l o c k m _ p I R e a l 3 Dl I n d e x = C a l c N e w I n d e x ( l I n d e x )这两个 m _ p I R e a l 3 D 已经不指向同一个对象了Fig 6.1 多次 Lock 时出现的问题。可以看出上图中,模块线程 1 两次
6、 Lock 之间,m_pIReal3D 的值已经发生了变化,这样会导致意想不到的错误。下图给出了这种问题的解决方法。模块线程 模块线程 模 块外部模块 外部模块 U p d a t e m _ p I R e a l 3 D . l I n d e xL o c k m _ p I R e a l 3 Dp I R e a l 3 D = m _ p I R e a l 3 DU n l o c k m _ p I R e a l 3 Dp I R e a l 3 D . l I n d e x = l I n d e xU p d a t e m _ p I R e a l 3 DL o c k m _ p I R e a l 3 Dm _ p I R e a l 3 D . R e a l e a s e ( )m _ p I R e a l 3 D = n e w C R e a l 3 D ( )U n l o c k m _ p I R e a l 3 Dl I n d e x = C a l c N e w I n d e x ( l I n d e x )l I n d e x = p I R e a l 3 D . l I n d e xFig 6.2 防止多次 Lock 出现问题。