zoukankan      html  css  js  c++  java
  • 如何检查线程是否死锁了?

    产生死锁的四个必要条件

    (1) 互斥条件:一个资源每次只能被一个进程(线程)使用。
    (2) 请求与保持条件:一个进程(线程)因请求资源而阻塞时,对已获得的资源保持不放。
    (3) 不剥夺条件 : 此进程(线程)已获得的资源,在末使用完之前,不能强行剥夺。
    (4) 循环等待条件 : 多个进程(线程)之间形成一种头尾相接的循环等待资源关系。

    可以使用 jstack或者pstack 和 gdb 工具对死锁程序进行分析。

    pstack: 功能是打印输出此进程的堆栈信息。可以输出所有线程的调用关系栈

    jstack:jstack是java虚拟机自带的一种堆栈跟踪工具,所以仅适用于java程序,功能跟pstack一样,但是更强大,可以提示哪个地方可能死锁了。

    pstack和jstack判断死锁,都需要多执行几次命令,观察每次的输出结果,才能推测是否死锁了。

    gdb

    1 运行程序,设置能影响程序运行的参数和环境 ;

    2 控制程序在指定的条件下停止运行;

    3 当程序停止时,可以检查程序的状态;

    4 当程序 crash 时,可以检查 core 文件;

    5 可以修改程序的错误,并重新运行程序;

    6 可以动态监视程序中变量的值;

    7 可以单步执行代码,观察程序的运行状态。

    线程死锁分析:

    1. 连续多次执行 $pstack <PID>   其中PID是进程号

       查看每个线程的函数调用关系的堆栈,观察每个线程当前的执行点是否在等待一个锁。

       多次执行该命令,发现某些线程的当前执行点不变,总是在等待同一个锁,就可以怀疑是否死锁了。

       如果怀疑哪些线程发生死锁了,可以采用gdb 进一步attach线程并进行分析。

    2. 执行$gdb -p <PID>  或者  $gdb attach <PID>

        (gdb) info thread

        (gdb) thread <thread ID>

    BTW:gdb的all-stop和non-stop模式 (GDBv7.0及之上版本支持)

    默认都是all-stop,即在某线程的代码里设置了断点,触发断点时所有的线程都会中断。

    non-stop是多线程调试的好帮手,某个线程里的断点触发了,其它线程还照常run,可以重现死锁的场景。

    想打开non-stop,可以修改~/.gdbinit,添加如下三行:

        set target-async 1
        set pagination off
        set non-stop on

    或者在进入gdb以后,依次执行以上三行,可以临时开启non-stop,退出gdb后失效。(猜是这样,需要实验验证)

    另外,如果多个线程走的一个代码块,停在了同一个断点上,例如只想让线程1和线程3继续,使用:

        (gdb) thread apply 3 1 continue

    BTW,判断热锁。热锁是指经常被打开关闭打开关闭的锁,由于多个线程对锁或者临界区的竞争造成的。

        * 频繁的线程的上下文切换:从操作系统对线程的调度来看,当 线程在等待资源而阻塞的时候,操作系统会将之切换出来,放到等待的队列,当线程获得资源之后,调度算法会将这个线程切换进去,放到执行队列中。
        * 大量的系统调用:因为线程的上下文切换,以及热锁的竞争,或 者临界区的频繁的进出,都可能导致大量的系统调用。
        * 大部分 CPU开销用在 “系统态 ”:线程上下文切换,和系统调用,都会导致 CPU在 “系统态 ”运行,换而言之,虽然系统很忙碌,但是 CPU用在 “用户态 ”的比例较小,应用程序得不到充分的 CPU资源。  
        * 随着 CPU数目的增多,系统的性能反而下降。因为 CPU数目多,同 时运行的线程就越多,可能就会造成更频繁的线程上下文切换和系统态的 CPU开销,从而导致更糟糕的性能。 

    可以通过脚本来固定时间间隔调用pstack,和查看系统资源使用情况的命令,比如top,分别将输出打印到log文件里。

    当然要每次执行命令都得打印时间戳。

    分析log文件,可以大概推测出热锁所在的位置。可以通过优化热锁,来提升程序的性能,例如吞吐量、响应时间。

  • 相关阅读:
    prometheus监控zookeeper
    prometheus监控mongo
    python游戏练手--乒乓球
    python游戏练手--贪吃蛇
    python爬虫练手--糗事百科图片获取
    Prometheus监控安装及使用(一)
    善用k8s explain
    k8s deployment
    k8s pod
    k8s deployment 金丝雀发布 更新的 暂停 恢复 回滚
  • 原文地址:https://www.cnblogs.com/ryn3316/p/9404698.html
Copyright © 2011-2022 走看看