多线程注意事项

多线程编程中应该注意的问题

 

1. 线程的优先级

多线程编程中要注意协调好各个线程的优先级。一般来说,控制线程的优先级要高于Worker线程。这样做,可以保证Client(最终用户或者其他模块)尽快得到响应。当控制线程是与最终用户交互的界面线程时更应如此,如果界面线程优先级较低,界面可能较长时间没有反应,用户很可能会怀疑命令是不是还没有开始执行。下面两张图给出了控制线程优先级不同对Client造成不同响应时间的对比。

Fig 1.1 控制线程优先级低,对用户响应时间较长

 

Fig 1.2 控制线程优先级高,对用户响应时间较短

 

 

2. 提高控制线程的响应速度

1) 减轻控制线程的负担,把更多的工作交给Worker线程来做。这么做的原因和第一条一样,是为了提高控制线程的响应速度,从而提高Client的满意度。

2) 注意Worker线程中信号量的使用,防止Worker线程长时间堵塞控制线程。典型的,控制线程和Worker线程会同时访问一个成员变量,并且其中至少有一个线程还要修改这个成员变量,如果Worker线程用信号量Lock了这个成员变量,然后做一些费时的工作(比如操作数据库),那么在它完成这些工作并Unlock这个成员变量之前,控制线程访问这个成员变量时都会被堵塞。所以,应该尽量减少Worker线程Lock的时间。下图中演示了堵塞发生的过程,红色的部分表示控制线程被堵塞了。

Fig 4.1 Worker线程堵塞控制线程的发生过程


Fig 4.2 防止Woker线程堵塞控制线程的方法。

 

上图给出的解决方法实际上是尽量减少Worker线程的Lock时间,把DB读出的数据暂时先放在临时变量中,仅当需要更新m_pData时才开始Lock

 

3. 做一个强有力的控制线程,减少Worker线程被唤醒的次数

对来自Client的事件,控制线程应该加一些基本的过滤,对于可以简单地判断出不需要Worker线程处理的事件(如一些在当前状态下不能处理,不需要处理,或者处理起来不费多少时间的事件),应该直接处理掉或者丢弃掉,而不是全部都发送给Worker线程。例如,Map中处理描画事件的方式就值得学习,当追加描画和擦除后再描画,两个事件同时到来时,Map的处理方式是仅处理擦除后再描画,追加描画直接忽略了。


4. 注意信号量的使用

在一个线程运行过程中,应该避免出现以下的使用方法:

Func

{

Lock();

Unlock();

Lock();

Unlock();

}

这是因为,如果第一次Unlock和第二次Lock之间,成员变量的值可能发生了变化,而如果Func函数恰好在两次Lock的时候都用到了那个发生了变化的成员变量,那么错误就有可能发生了。

Fig 6.1 多次Lock时出现的问题。

 

可以看出上图中,模块线程1两次Lock之间,m_pIReal3D的值已经发生了变化,这样会导致意想不到的错误。下图给出了这种问题的解决方法。

Fig 6.2 防止多次Lock出现问题。

 

转载:http://wenku.baidu.com/link?url=ahyrgwtgC1yRoL5IUkMSHEestmOiKEhwUrflL8BcWATE9YnwEGTVDNy9CXF_oukIzd3fAVclTFPzHyLgi-QZUdS-nahiAAcxNJnsuKZJ65K

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值