windows 多线程编程的几点经验

1、不要在子线程操作UI控件
2、如果你操作了,也绝对不能调用UpdateData来更新界面,否则程序Crash
3、这一条建立在第一条基础上---你在子线程操作UI控件,不可以让主线程等待某些条件(如等待子线程关闭,而子线程正在操作UI、等待进


入临界区,而子线程已经进入,并且操作UI),否则会出现假死...
4、最好方案:子线程操作数据,完成之后,通知主线程进行更新....


下面来自网上,分享一下:


windows 多线程编程的几点经验 (防止死锁)

1) 不要在线程函数体内操作MFC控件,不要再线程里面调用UpdateData函数更新用户界面,而应该尽量采用发送消息的方式,在主线程的消

息响应函数中操作控件;
 
2)不建议采用SendMessage往主线程发送消息,因为它是同步的,阻塞的,可以考虑采用PostMessage代替;
 
3)线程退出时,尽量不要使用TerminateThread函数,而尽可能的让线程自己退出;
 
4) 当线程退出时,必须先等待工作者线程退出,主线程才退出,但是在主线程里面不要使用WaitForSingleObject或WaitForMultiObjects等
待线程结束,因为它可能造成死锁,当主线程使用这两个函数时,主线程就挂起了,尤其在第 (1), (2) 种情况下,工作者线程还在调用主线
程里面的资源,这样造成死锁;
 
5) 为了防止退出死锁的发生,尽量使用MsgWaitForMultipleObjects函数,因为该函数等待时,可以等待线程句柄 有信号,而且还可以等待
消息,不会造成死锁;
 


1. 原子访问:(从来不会把线程切换到等待状态)
InterlockedExchangeAadd; // 原子加减
InterlockedIncrement;
InterlockedExchange; // 原子赋值 应用:旋转锁(少用)
InterlockedExchangePointer;
 
2. 高速缓存行:
CPU会将所要取的内存数据的临近数据存到高速缓存行,因此将只读和可读写的数据适当分开组织可提高性能。
指针永远不需要volatile关键字修饰,因为会永远读取内存地址,编译器不会做任何优化。
 
3. 高级同步
关键段(critical section):锁代码(只能在同一个进程中同步,无法指定最长等待时间:容易死锁)
如果有全局CRITICAL_SECTION对象,则可以用它锁不同的代码段;
EnterCriticalSection和LeaveCriticalSection;
必须初始化和反初始化:IntializeCriticalSection和DeleteCriticalSection;
优点:内部使用Interlock函数,速度快;
缺点:无法用来在多个进程之间对进程进行同步;
 
多处理器调用没有问题,只有一个处理器的线程能执行,其余都要等待;
由于线程进入等待状态要被系统从用户态切换到内核态,因此在使用关键段是应该总是同时使用旋转锁:
IntializeCriticalSectionAndSpinCount,旋转锁循环次数经典值是4000;
Slim读/写锁
 
以上方法的线程同步将保证线程在用户态:速度快。


子线程操作UI控件出错原因:


当创建窗口的线程和UpdateData调用所在的线程不是同一线程的时候MFC就会出错。为MFC把部分信息储存在线程的TLS中,这些信息对于MFC
的执行非常重要,因此MFC会在很多代码里面检查线程状态是否正确。当在线程中调用父窗口的UpdateData时,相对于UpdateData的线程环境
已经改变了,所以就会出错了。
可以使用如下方案:
1,在线程中使用 pDLG->GetDlgItem(ID)->SetWindowText(str)
2,线程向父对话框发送自定义消息,消息响应函数里调用UpDateData


不要在线程函数体内操作MFC控件,因为每个线程都有自己的线程模块状态映射表,在一个线程中操作另一个线程中创建的MFC对象,会带来
意想不到的问题。更不要在线程函数里,直接调用UpdataData()函数更新用户界面,这会导致程序直接crash。而应该通过发送消息给主线程
的方式,在主线程的消息响应函数里操作控件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值