为什么在工作者线程中直接销毁主线程的窗口会出错?debug差不多一整天,把我弄得差不多半死之后,我从网上得知,工作者线程中不能使用界面线程的指针或对象,直接销毁窗口!
举个例子,就是这种情况:
1 2 3 4 5 6 7 8 9 10 11 12 | void CMainFrame::OnSomeAction() { … m_pDlg->ShowWindow(SW_SHOW); } UINT ThreadProc(LPVOID lParam) { … pDlg->DestroyWindow();//pDlg引用的m_pDlg } |
1 | 网上的解释如下,直接Copy,懒得写了! |
可能初学者没有意识到,应用程序中创建的对象并非是整个进程共享的。在Windows应用程序体系中,对象是线程”私有”的(也就是调用对象方法不能超出线程边界)!也就是说,A线程创建了B对象,则B对象归A线程所有,A线程负责为B对象处理所有的消息(如果有的话)收发工作并交给B的消息处理函数或发到其他窗口对象去,线程结束时负责释放B对象。由于通常的应用程序创建对象及调用对象方法都是在主线程中进行的,因而不存在什么问题;但如果一个应用程序的多个线程需要操作同一个对象时,情况就会大不一样了。一个常见的多线程示例是:A线程(通常是主线程)创建一个对话框B,创建C线程负责处理后台工作,并将处理进展情况报告给B(例如在B上显示一些文字或图形信息或更新B的显示界面等)。初学者往往会犯这样的错误:将B对象的指针传递给C线程的线程函数,让C线程直接调用B对象的方法添加信息或更新显示界面。这样做对于一个简单的窗口类(如显示处理进度的对话框)而言,有时确实也成功了;但这要冒很大的潜在风险,那就是这种处理方法有时会莫名其妙的出错(通常是访问冲突导致的)!而对于一个复杂的类对象,采用类似的处理方法出现问题的可能性会大大增加,往往根本不能工作。
此问题的解决办法就是:向主线程发消息,由主线程自己处理!
写了个示例,演示了正确与错误的方法,大家可以下载看看
运行截图:
正确的方法:
错误的方法:
附件下载:


原来这是沙发哇…
都开始研究底层的东东了…
这不是底层的东东,多线程是很基础的内容
内容不多,很容易学。真的
我是以前学的基础,都忘完了。
呵呵,老师一般不会讲多少实用的技术,多线程,老师一般都没讲过的
嗯,自学…
前排围观。。
还是看不懂0 0··········
有空写点别的!
好样的。。大傻瓜再次来转一圈
我是小傻瓜
什麼是工作者線程啊
即工作线程,相对界面线程来说的,简单地说即是在后台同步处理一些数据,而不使前台失去响应
難道是一個任務在前台和後台同時處理麼?是同時處理一個任務還是同時處理兩個相同的任務
举个一般的多线程程序的例子!比如后台工作线程负责处理数据,前台界面线程就负责与用户进行交互,这两个是同时进行的!
有些单线程的程序就是,运行的时候,前台好像死掉了,那是因为它必须把数据处理完了,才能与用户进行交互!
就好像一個店鋪裡只有一個人,然後一個顧客來買東西,而東西放在後面的房間裡,然後賣家要跑到後面的房間裡找那樣商品,是差不多這樣子麼?
简单地说,就是两个程序块同时在执行
哦。。。果然kita只有在接觸了後才能明白
就是有两个店员买一个东西,他们有可能同时要拿东西,然后就打架了~
呵呵……
我显然懂这个呗 顶一顶~~~
显然
好多西瓜哦!好想吃,可爱的西瓜
哈哈。真逗的西瓜
每次都很简单啊
GUI(窗口)只能由主线程访问,几乎是所有GUI系统的共同性质。Windows、GTK、Android莫不是如此。
但好像有个例外,是WPF,具体是不是我也没研究过。
呃,不是访问,是修改
界面线程也可以单独开n个,界面线程也不一定是主线程哦!
呵呵,受教了
界面线程只是增加了窗口消息处理而已,没什么特别的
围观吧!!!不懂多线程
欢迎围观
看的头有点晕,顶顶
坐坐学习下
欢迎围观
kita是來玩西瓜頭的
我表示完全看不懂。
~
写的不错,看的有点小晕,
了解下就好了。
eggpain,不给力啊~
egghurt
各种不懂… = =
只想评价下你的表情太有意思了..
看不懂……
晕晕的,不懂。
瓜哥玩的太深了~~
玩的最高境界就是工作即是玩,玩即是工作,不给加班费都自愿加班
这么玩就太自虐了
不懂这个
虽然很基础,但是我还是不怎么懂啊!
一屏西瓜~
“`~“`
完全看不懂
这就对了
哈哈,玩玩表情哈。
相当蛋疼。我是不会去研究的。
祝C瓜哥新年快乐,学习进步,工作进步!!!O(∩_∩)O~
兔年快乐
windows多线程却是这样,父线程造就子线程,子线程反过来毁掉父线程,那不乱套了么……
不是由子线程来毁掉主线程,它们根本就没有父子关系
再者,我只是想销毁窗口而已,又不是销毁主线程
你写游戏应该会遇到很多线程的东西,以后做了就知道了
明显C瓜哥没有查阅MSDN,官方文档已经声明过….
这真还没注意到