V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
RLib
V2EX  ›  程序员

分享一个死锁案例

  •  
  •   RLib ·
    Rprop · 2017-07-30 00:48:00 +08:00 · 3149 次点击
    这是一个创建于 2683 天前的主题,其中的信息可能已经有所发展或是发生改变。
    UI 线程在等待线程池完成销毁, 但是线程池里的线程又给 UI 线程 POST 了消息(不是 APC),于是挂了,总结来讲,尽量不要让 UI 线程去做任何可能的等待
    10 条回复    2017-08-03 03:10:38 +08:00
    RLib
        1
    RLib  
    OP
       2017-07-30 00:49:29 +08:00
    这里的 POST 表述不准确,应该是 SEND
    yangff
        2
    yangff  
       2017-07-30 01:06:52 +08:00
    嗯……
    一个稍微比较坑一点的情节是这样的(
    比如 UI 线程接到某个 event,去尝试销毁另一个线程持有的对象(通过线程间通讯去要求对方销毁),而那个线程是这个 event 实际上的发起者…… 于是他在等待 eventhandler 结束……

    最关键的是,你在用 await + async 写这些代码的时候无比畅快……

    比如 label1.Text = await DoCompution()之类的……

    实际上都多多少少有些问题(
    limhiaoing
        3
    limhiaoing  
       2017-07-30 21:50:49 +08:00
    @yangff
    ``` cs
    label1.Text = await DoCompution();
    ```
    DoCompution 实现正确的情况下会有问题?
    yangff
        4
    yangff  
       2017-07-30 22:06:01 +08:00
    @limhiaoing 正确情况下是不会有问题的……

    然而你可能会再在里面写上一些看起来没问题的代码(或者你调用了一些库的实现有一些问题),导致整个东西 boom 掉……

    而且这些东西可能不是很可以预计…… 毕竟有可能有的库就是二进制分发的…… 连源代码都没有
    limhiaoing
        5
    limhiaoing  
       2017-07-30 22:08:40 +08:00
    @yangff
    举个具体的例子看下呢?
    limhiaoing
        6
    limhiaoing  
       2017-07-30 22:11:20 +08:00
    @yangff
    指的是看起来没问题的代码。
    yangff
        7
    yangff  
       2017-07-30 22:32:59 +08:00
    @limhiaoing 不是很好举例子…… 一下想不起来之前出的问题了…… 大概的问题是出在
    DoCompution 这里面调用了 DLL,这个 DLL 本身有一些问题会导致计算的这个线程等待一个 UI 线程那边的锁……

    反正只用 await/async 应该是安全的
    yangff
        8
    yangff  
       2017-07-30 22:34:55 +08:00
    抽象一点说的话就是这样的,不过直接这样看其实感觉问题是很明显啦……

    UIThread:
    1. Lock
    2. await (hold lock)

    Computation Thread:
    1. Lock
    2. deadlock..
    RLib
        9
    RLib  
    OP
       2017-07-31 16:56:02 +08:00
    @limhiaoing 旁观者清当局者迷,大概说的就是这个,这你让别人怎么给你举例呢...
    在解决完一个 bug 我们基本都会有个小结,但其实回顾来看,很少 bug 是超出认知范围的...
    geelaw
        10
    geelaw  
       2017-08-03 03:10:38 +08:00
    一个很矛盾的事情:如果你的 UI 线程等待一个线程池,那么你的 UI 已经卡了,这已经很糟糕了。

    正确的异步是让线程池完成销毁的最后步骤为通知 UI 线程自己搞定了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3591 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:42 · PVG 12:42 · LAX 20:42 · JFK 23:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.