首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 求教高手解答线程死锁问题,小白勿扰 [已结贴,结贴人:Fannyyang_ly]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Fannyyang_ly
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 揭帖率:
    发表于: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  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ouyh12345
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

    发表于:2008-06-13 16:20:071楼 得分:0
    在while循环里,加个Sleep(1),释放控制权
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Fannyyang_ly
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:22:082楼 得分:0
    引用 1 楼 ouyh12345 的回复:
    在while循环里,加个Sleep(1),释放控制权


    试过了。。。没用。。还是一样会死循环
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • stonewater
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:22:453楼 得分:0
    你用的不是信号量吧
    是个普通的变量吧
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 5

      2

      13

    发表于:2008-06-13 16:26:034楼 得分:0
    这种写法不行,在if (!writeflag)和writeflag=true这两行代码中间可能会发生线程切换,建议使用同步对象,如果考虑效率问题可以用InterlockedXxx函数来处理。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • vcPlayer
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:26:455楼 得分:0
    用“volatile” 来声明变量writeflag:

    volatile bool writeflag;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • DarknessTM
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:26:496楼 得分:0
    其中一个线程获得这个信号量的 概率太低了,因为一个线程的丢失信号量的时候只有几条汇编指令……
    你应该在丢失信号量后 加sleep 来提高概率
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • DarknessTM
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:27:377楼 得分:0
    Writeflag=false;
    sleep(50);
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ls443085074
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:27:458楼 得分:0
    第一个问题,你并没有使用信号量,虽然你模拟了那种效果。如此,我想你在运行的时候还是可能会出现资源竞争的情况以致死锁。
    第二个问题,我敢保证你在线程里打断点,你会发现你的主线程也会像你说的线程那样永远执行不过B点,原因是你单步的那个线程或得的时间片被你浪费了,那个没断点的线程跑得快,如果你有时间你可以去尝试,不停的按F9,我想你总有一次会进去的。

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • fairyprince
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:28:039楼 得分:0
    贴出的详细代码
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jameshooo
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

      4

    发表于:2008-06-13 16:28:2710楼 得分:0
    用普通布尔变量很难起到真正的同步作用,需要使用真正的同步对象
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cppwin
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:28:3211楼 得分:100
    原因:
    SetItemText() 其实是SendMessage()
    消息发出后,等待主线程响应完成,
    但主线程正在while(true)循环中,不能响应消息.
    于是SendMessage()无法返回.
    于是SetItemText()继续等待.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • vcPlayer
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:33:2912楼 得分:0
    引用 5 楼 vcPlayer 的回复:
    用“volatile” 来声明变量writeflag:

    volatile bool writeflag;


    另外你两个线程在同时写这个变量,需要加上一个同步对象!用互斥锁或临界区都行。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • stonewater
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:35:0613楼 得分:0
    还要看while (true)
    {
        if (!writeflag)
        {
          writeflag=true;
          ....................//对列表操作
            writeflag=false;
          break;
        }
    }
    是在哪个函数里,如果是在处理SetItemText的消息的函数里,哪就锁死了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cppwin
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:35:2414楼 得分:0
    解决办法很猥琐.
    1.在while(){}加一个 GetMessage() DisapatchMessage()

    2.不要在另外的线程中使用SetItemText

    3.将while()拿到工作线程中去做.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • stonewater
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 16:37:1815楼 得分:0
    就你的代码可以用postmessage代替
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhoujianhei
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 17:12:3816楼 得分:0
    引用 15 楼 stonewater 的回复:
    就你的代码可以用postmessage代替

    注意界面线程和工作线程的区别!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jason_wentzel
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 17:23:5117楼 得分:0
    用下面的试试
    EnterCriticalSection
    // 要互斥的对象
    LeaveCriticalSection

    还有在while循环里,加个Sleep(1),释放控制权,要不然CPU时间全被它占用了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • simon031187
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 17:41:2418楼 得分:0
    引用 11 楼 cppwin 的回复:
    原因:
    SetItemText() 其实是SendMessage()
    消息发出后,等待主线程响应完成,
    但主线程正在while(true)循环中,不能响应消息.
    于是SendMessage()无法返回.
    于是SetItemText()继续等待.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • bennywingggg
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-13 20:59:5219楼 得分:0
    如果是简单处理的话,CreateEvent, WaitForSingleObject, SetEvent, 两次Sleep(0),效果就很好了,这样的效率会比较好。
    EnterCriticalSection, LeaveCriticalSection, Sleep和volatile一样,在资源比较紧张的时候容易挂掉。
    如果不介意时间的话,不妨试一下CreateIoCompletionPort
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 303afei
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-06-16 09:23:3420楼 得分:0
    引用 11 楼 cppwin 的回复:
    原因:
    SetItemText() 其实是SendMessage()
    消息发出后,等待主线程响应完成,
    但主线程正在while(true)循环中,不能响应消息.
    于是SendMessage()无法返回.
    于是SetItemText()继续等待.


    同意
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved