首页
新闻
论坛
群组
Blog
文档
下载
读书
Tag
网摘
搜索
.NET
Java
游戏
视频
人才
外包
培训
数据库
书店
程序员
欢迎您:
游客
| 退出
| 登录
注册
帮助
我的帖子
我参与的帖子
我的空间
我的网摘
CSDN
CSDN社区
VC/MFC
进程/线程/DLL
将帖子提前
放进我的网摘
推荐给好友
我要提问
帖子加分
生成帖子
置顶
推荐(加精)
取消推荐(加精)
锁定帖子
移动帖子
取消引用
结贴去...
管理菜单
页面风格切换
标准风格
老版本论坛
求教高手解答线程死锁问题,小白勿扰
[已结贴,结贴人:Fannyyang_ly]
加为好友
发送私信
在线聊天
Fannyyang_ly
猪宝宝
等级:
可用分等级:
乞丐
总技术专家分:
0
总技术专家分排名:
311804
揭帖率:
93.33%
发表于:
2008-06-13 16:11:52
楼主
我建立了一个单文档程序,在其中又创建了一个线程,我用一个互斥信号量
writeflag来互斥访问一个列表控件myList。
主进程访问列表控件程序大概如下 :
while (true)
{
if (!writeflag)
{
writeflag=true;
....................//对列表操作
writeflag=false;
break;
}
}
还有一个线程访问列表控件程序如下:
if (!writeflag)
{
writeflag=true; //A点
myList.SetItemText(2,xxxxx); //B点
Writeflag=false;
}
结果发现在调试时:当线程走过A点,开始SetItemText时,主程序进入while循环,
于是整个程序开始死循环,好像B点永远没执行完,没有把Writeflag置成false;
主程序永远在等着释放信号量。
想请问高人。。为什么会这样,按我理解,线程应该很快走完释放信号量,主程序马上
得到信号量开始处理。我知道为什么会产生死锁的。。CPU是core2双核得。。。
想告诉我有其他方法的小白勿扰,谢谢。我只想知道为什么会死锁。
问题点数:
100
回复次数:
20
显示所有回复
显示星级回复
显示楼主回复
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
ouyh12345
五岭散人
等级:
可用分等级:
长工
总技术专家分:
45529
总技术专家分排名:
178
2
发表于:
2008-06-13 16:20:07
1
楼 得分:
0
在while循环里,加个Sleep(1),释放控制权
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
Fannyyang_ly
猪宝宝
等级:
可用分等级:
乞丐
总技术专家分:
0
总技术专家分排名:
311804
发表于:
2008-06-13 16:22:08
2
楼 得分:
0
引用 1 楼 ouyh12345 的回复:
在while循环里,加个Sleep(1),释放控制权
试过了。。。没用。。还是一样会死循环
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
stonewater
小队长
等级:
可用分等级:
小地主
总技术专家分:
2171
总技术专家分排名:
9741
发表于:
2008-06-13 16:22:45
3
楼 得分:
0
你用的不是信号量吧
是个普通的变量吧
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
cnzdgs
回贴亦是善举
等级:
可用分等级:
乞丐
总技术专家分:
105613
总技术专家分排名:
45
5
2
13
发表于:
2008-06-13 16:26:03
4
楼 得分:
0
这种写法不行,在if (!writeflag)和writeflag=true这两行代码中间可能会发生线程切换,建议使用同步对象,如果考虑效率问题可以用InterlockedXxx函数来处理。
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
vcPlayer
没有星星,努力做太阳!
等级:
可用分等级:
掌柜
总技术专家分:
8311
总技术专家分排名:
2426
发表于:
2008-06-13 16:26:45
5
楼 得分:
0
用“
volatile
” 来声明变量writeflag:
volatile
bool writeflag;
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
DarknessTM
单身MM请找我
等级:
可用分等级:
中农
总技术专家分:
3923
总技术专家分排名:
5213
发表于:
2008-06-13 16:26:49
6
楼 得分:
0
其中一个线程获得这个信号量的 概率太低了,因为一个线程的丢失信号量的时候只有几条汇编指令……
你应该在丢失信号量后 加sleep 来提高概率
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
DarknessTM
单身MM请找我
等级:
可用分等级:
中农
总技术专家分:
3923
总技术专家分排名:
5213
发表于:
2008-06-13 16:27:37
7
楼 得分:
0
Writeflag=false;
sleep(50);
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
ls443085074
等级:
可用分等级:
中农
总技术专家分:
436
总技术专家分排名:
35613
发表于:
2008-06-13 16:27:45
8
楼 得分:
0
第一个问题,你并没有使用信号量,虽然你模拟了那种效果。如此,我想你在运行的时候还是可能会出现资源竞争的情况以致死锁。
第二个问题,我敢保证你在线程里打断点,你会发现你的主线程也会像你说的线程那样永远执行不过B点,原因是你单步的那个线程或得的时间片被你浪费了,那个没断点的线程跑得快,如果你有时间你可以去尝试,不停的按F9,我想你总有一次会进去的。
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
fairyprince
精灵王子
等级:
可用分等级:
掌柜
总技术专家分:
5963
总技术专家分排名:
3548
发表于:
2008-06-13 16:28:03
9
楼 得分:
0
贴出的详细代码
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
jameshooo
胡柏华
等级:
可用分等级:
中农
总技术专家分:
47685
总技术专家分排名:
172
2
4
发表于:
2008-06-13 16:28:27
10
楼 得分:
0
用普通布尔变量很难起到真正的同步作用,需要使用真正的同步对象
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
cppwin
cppwin
等级:
可用分等级:
中农
总技术专家分:
2609
总技术专家分排名:
8098
发表于:
2008-06-13 16:28:32
11
楼 得分:
100
原因:
SetItemText() 其实是SendMessage()
消息发出后,等待主线程响应完成,
但主线程正在while(true)循环中,不能响应消息.
于是SendMessage()无法返回.
于是SetItemText()继续等待.
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
vcPlayer
没有星星,努力做太阳!
等级:
可用分等级:
掌柜
总技术专家分:
8311
总技术专家分排名:
2426
发表于:
2008-06-13 16:33:29
12
楼 得分:
0
引用 5 楼 vcPlayer 的回复:
用“volatile” 来声明变量writeflag:
volatile bool writeflag;
另外你两个线程在同时写这个变量,需要加上一个同步对象!用互斥锁或临界区都行。
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
stonewater
小队长
等级:
可用分等级:
小地主
总技术专家分:
2171
总技术专家分排名:
9741
发表于:
2008-06-13 16:35:06
13
楼 得分:
0
还要看while (true)
{
if (!writeflag)
{
writeflag=true;
....................//对列表操作
writeflag=false;
break;
}
}
是在哪个函数里,如果是在处理SetItemText的消息的函数里,哪就锁死了
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
cppwin
cppwin
等级:
可用分等级:
中农
总技术专家分:
2609
总技术专家分排名:
8098
发表于:
2008-06-13 16:35:24
14
楼 得分:
0
解决办法很猥琐.
1.在while(){}加一个 GetMessage() DisapatchMessage()
或
2.不要在另外的线程中使用SetItemText
或
3.将while()拿到工作线程中去做.
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
stonewater
小队长
等级:
可用分等级:
小地主
总技术专家分:
2171
总技术专家分排名:
9741
发表于:
2008-06-13 16:37:18
15
楼 得分:
0
就你的代码可以用postmessage代替
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
zhoujianhei
高手.高手.高高手
等级:
可用分等级:
小地主
总技术专家分:
14202
总技术专家分排名:
1078
发表于:
2008-06-13 17:12:38
16
楼 得分:
0
引用 15 楼 stonewater 的回复:
就你的代码可以用postmessage代替
注意界面线程和工作线程的区别!
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
jason_wentzel
开源盛世
等级:
可用分等级:
掌柜
总技术专家分:
2382
总技术专家分排名:
9150
发表于:
2008-06-13 17:23:51
17
楼 得分:
0
用下面的试试
EnterCriticalSection
// 要互斥的对象
LeaveCriticalSection
还有在while循环里,加个Sleep(1),释放控制权,要不然CPU时间全被它占用了
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
simon031187
等级:
可用分等级:
富农
总技术专家分:
561
总技术专家分排名:
29748
发表于:
2008-06-13 17:41:24
18
楼 得分:
0
引用 11 楼 cppwin 的回复:
原因:
SetItemText() 其实是SendMessage()
消息发出后,等待主线程响应完成,
但主线程正在while(true)循环中,不能响应消息.
于是SendMessage()无法返回.
于是SetItemText()继续等待.
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
bennywingggg
小丁宁
等级:
可用分等级:
长工
总技术专家分:
0
总技术专家分排名:
311804
发表于:
2008-06-13 20:59:52
19
楼 得分:
0
如果是简单处理的话,CreateEvent, WaitForSingleObject, SetEvent, 两次Sleep(0),效果就很好了,这样的效率会比较好。
EnterCriticalSection, LeaveCriticalSection, Sleep和volatile一样,在资源比较紧张的时候容易挂掉。
如果不介意时间的话,不妨试一下CreateIoCompletionPort
修改
删除
举报
引用
回复
加为好友
发送私信
在线聊天
303afei
等级:
可用分等级:
富农
总技术专家分:
585
总技术专家分排名:
28890
发表于:
2008-06-16 09:23:34
20
楼 得分:
0
引用 11 楼 cppwin 的回复:
原因:
SetItemText() 其实是SendMessage()
消息发出后,等待主线程响应完成,
但主线程正在while(true)循环中,不能响应消息.
于是SendMessage()无法返回.
于是SetItemText()继续等待.
同意
修改
删除
举报
引用
回复
将帖子提前
放进我的网摘
推荐给好友
我要提问
帖子加分
结贴去...
管理菜单
页面风格切换
标准风格
老版本论坛
网站简介
-
广告服务
-
网站地图
-
帮助
-
联系方式
-
诚聘英才
-
English
-
问题报告
北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
abc推荐给好友