操作UI的线程退出问题。求教

DontKissBossAss 2010-08-09 12:46:53
上一次发帖,说了老师教的一个操作UI的线程退出方法。这段时间就用这个方法,本来挺爽,发现有问题了,方法如下

在执行线程退出时执行如下

m_bFlagOfThreadRunEable = false; //线程运行的标志置为false;

while(1)
{
if(WaitForSingleObject(m_pSnapThread, 0) == WAIT_OBJECT_0)
{
break;
}

MSG msg;
if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if(有数据了)
{
m_bFlagOfHaveData = true;
}
}


自从知道了这点之后,在这几个月,写的小玩意,用到操作UI的线程时候,我就一直copy着,但是最近偶然一次闹鬼现象,叫我研究了N天才知道原因
这问题是我偶然间发现的,程序的逻辑是:程序的逻辑是,当点击关闭线程之后(此时我认为,线程采集到了信息,虽然没采集完成,但是已经有数据了)才点击 开始*** 按钮。

在“开始×××”按钮响应时,会检验是不是有数据了

if(!bFlagOfHaveData)
return;

当我快速执行如下步骤时候,闹鬼了
1:点击“结束线程”
2:点击开始×××

经过研究,程序将执行如下代码
if(!bFlagOfHaveData)
return;

原来都是我把消息循环驱动起来的原因。

想问下大家,在这种操作UI的线程退出时。大家怎么操作的,望不吝赐教
...全文
210 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
DontKissBossAss 2010-08-12
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 cattycat 的回复:]

感觉这个只能与你具体的应用设计一个好的避免竞争的方法,没有一个统一的模型让你在各种情况下都用。
[/Quote]

谢谢一直关注。研究来去,只有一个办法。kill掉。。。terminal

暴力强奸了她,也强奸了我的认识。。
cattycat 2010-08-12
  • 打赏
  • 举报
回复
感觉这个只能与你具体的应用设计一个好的避免竞争的方法,没有一个统一的模型让你在各种情况下都用。
DontKissBossAss 2010-08-11
  • 打赏
  • 举报
回复
知道的说下哈。
名刀秋水 2010-08-10
  • 打赏
  • 举报
回复
跟一下,看看从哪里结束的
cattycat 2010-08-10
  • 打赏
  • 举报
回复
其实你这个处理模型仍然隐含竞争,所以在处理数据的消息函数中除法信号比在开始XXX中触发信号要可靠一些。
cattycat 2010-08-10
  • 打赏
  • 举报
回复
估计这里是WaitForSingleObject那里直接break退出循环了,所以直接执行了代码2.

你快速执行时,可能是由于数据的消息处理函数还需要一定的时间,代码1那里判断还是没数据,第二次WaitForSingleObject等到了信号量就跳出while循环了。

WaitForSingleObject(m_pSnapThread, 0)
m_pSnapThread这个信号量是谁释放的?
DontKissBossAss 2010-08-10
  • 打赏
  • 举报
回复
描述的不清楚?
DontKissBossAss 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 cattycat 的回复:]

其实你这个处理模型仍然隐含竞争,所以在处理数据的消息函数中除法信号比在开始XXX中触发信号要可靠一些。
[/Quote]

竞争关系是必然存在的,试想一下,你写了一个库,希望用户传入一个回调函数指针,而你当某件事发生时候,调用这个回调。

这个回调时用户写的,什么操作都可能发生,比如操作UI。往UI打印东西

你的库还要提供退出机制,因为你开辟了线程,当使用者点击退出的时候,实际上会调用你提供的清理接口,

这个接口直接枪杀的那个线程?不会的。

你肯定要等待线程回调函数返回。注意了,这个时候,一个强烈的争夺发生了,用户点击一个按钮,去等待你的清理函数执行完成。(主线程卡住了),你线程在去写UI,因为主线程卡哪了,等线程,而写UI是需要主线程辅助的,这个时候,因为主线程卡了,线程也卡了,都死锁了。。。


我上面的办法是加了,小区驱动,主线程卡住咱不管,但是咱要避免线程卡住,就驱动起来了消息,使线程能继续打印东西。

这就出来了上述的问题

你们怎么清理操作UI的线程?
DontKissBossAss 2010-08-09
  • 打赏
  • 举报
回复
我知道我代码有些罗嗦,比如 if(有数据了) 这段就多多余,但是,这只是一个比喻。我只是在引入问题。,实际情况时,老师教我写了一个库,调用时候要添加回调函数指针,而回调函数内我可能写UI,这时候就是退出问题了。
DontKissBossAss 2010-08-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 cattycat 的回复:]
没看明白你
1:点击“结束线程”
2:点击开始×××
是啥关系,结束线程是退出执行线程么?点击开始XXX是上面列出的代码么?
快速执行时你是说仍然没有获得数据?那可能是因为发出消息到消息处理还有一段距离。
你应该在结束线程那里确定判断数据到达,然后ButtonEnable使可以点击开始xxx,要不然用户乱点,先开始xxx,然后再点击结束线程呢?
不知道我理解的对不。
[/Quote]

我给你演示一下吧,理想情况下,我要执行的代码连续如下(假设没有函数了。。)

m_bFlagOfThreadRunEable = false; //线程运行的标志置为false;

while(1)
{
if(WaitForSingleObject(m_pSnapThread, 0) == WAIT_OBJECT_0)
{
break;
}

MSG msg;
if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
//代码1
if(有数据了)
{
m_bFlagOfHaveData = true;
}
}

//代码2
if(!bFlagOfHaveData)
return;


但是有驱动消息以后,代码1不执行,而跑到代码2开始执行了
因为如下
1:事实上,代码2和代码1响应的是不同的BUTTON,
2:我把消息驱动起来了,结束一时候,在while(1)内时候,点击了开始×××,从而,
if(有数据了)
.....没有执行
DontKissBossAss 2010-08-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 healer_kx 的回复:]
UI线程退出,发生WM_QUIT就可以了。
[/Quote]

结束线程这个操作,是主线程发起的,(在UI上点击结束。),线程怎么接受这个消息呢?我的线程代码只是一个循环,
DontKissBossAss 2010-08-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 cattycat 的回复:]
没看明白你
1:点击“结束线程”
2:点击开始×××
是啥关系,结束线程是退出执行线程么?点击开始XXX是上面列出的代码么?
快速执行时你是说仍然没有获得数据?那可能是因为发出消息到消息处理还有一段距离。
你应该在结束线程那里确定判断数据到达,然后ButtonEnable使可以点击开始xxx,要不然用户乱点,先开始xxx,然后再点击结束线程呢?
不知道我理解的对不。
[/Quote]
结束线程和开始××是先后关系,必须先结束,才开始×××

点击结束线程,时候理论情况下,主线程应该阻塞在那块等待线程退出,因为我把消息驱动起来了(主线程不能阻塞,因为线程可能操作UI),为解决这个矛盾,才驱动消息,

但是被驱动起来以后,变成非阻塞的了,点击开始×××,发生,

if(有数据了)
{
m_bFlagOfHaveData = true;
}
有了消息启动以后,上述代码没有执行,而执行了
开始***里面的
if(!m_bFlagOfHaveData)

cattycat 2010-08-09
  • 打赏
  • 举报
回复
没看明白你
1:点击“结束线程”
2:点击开始×××
是啥关系,结束线程是退出执行线程么?点击开始XXX是上面列出的代码么?
快速执行时你是说仍然没有获得数据?那可能是因为发出消息到消息处理还有一段距离。
你应该在结束线程那里确定判断数据到达,然后ButtonEnable使可以点击开始xxx,要不然用户乱点,先开始xxx,然后再点击结束线程呢?
不知道我理解的对不。
hslinux 2010-08-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 healer_kx 的回复:]

UI线程退出,发生WM_QUIT就可以了。
[/Quote]

~~~
ayw215 2010-08-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 healer_kx 的回复:]

UI线程退出,发生WM_QUIT就可以了。
[/Quote]
发送消息
处理消息
healer_kx 2010-08-09
  • 打赏
  • 举报
回复
UI线程退出,发生WM_QUIT就可以了。

64,691

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧