代码之家  ›  专栏  ›  技术社区  ›  Chenna V

进程死锁,Unix命令?

  •  3
  • Chenna V  · 技术社区  · 15 年前

    我想知道如何知道进程的线程是否在Unix/Linux机器上被死锁了?此外,是否有一个命令用于了解流程处于哪个阶段(或状态)?如果你知道任何工具,请提出建议。谢谢您。

    3 回复  |  直到 15 年前
        1
  •  1
  •   dennycrane    15 年前

    尝试使用跟踪系统调用的工具,例如 strace 在Linux或 tusc 在HP-UX上。当发生死锁时,您应该看到进程挂起在阻塞调用中。不过,这并不是一个积极的证据。可能是普通街区。然后需要确定是否可以在某个时间解析块。这需要了解流程正在等待的资源。

    例子

    在RHEL4上存在一个…怪癖。。。可能导致 ctime 陷入僵局。请在下面查找显示此行为的示例程序:

    #include <sys/time.h>
    #include <time.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    volatile char *r;
    
    void handler(int sig)
    {
        time_t t;
    
        time(&t);
        r = ctime(&t);
    }
    
    int main()
    {
        struct itimerval it;
        struct sigaction sa;
        time_t t;
        int counter = 0;
    
        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = handler;
        sigaction(SIGALRM, &sa, NULL);
    
        it.it_value.tv_sec = 0;
        it.it_value.tv_usec = 1000;
        it.it_interval.tv_sec = 0;
        it.it_interval.tv_usec = 1000;
        setitimer(ITIMER_REAL, &it, NULL);
    
        while(1) {
            counter++;
            time(&t);
            r = ctime(&t);
            printf("Loop %d\n",counter);
        }
    
        return 0;
    }
    

    这通常会在几千次迭代之后进入死锁。现在,连接 斯特拉斯 像这样

    strace -s4096 -p<PID>
    

    哪里 PID 是程序的进程id。您将看到程序挂起 FUTEX_WAIT 在参数中。(由于我目前无法使用RHEL4机器,请原谅,我无法引用整条线路的报价。)。

        2
  •  2
  •   Amr Mostafa    15 年前

    多亏了 /proc/<pid>/syscall ,这就是我最终实现 quick and dirty processes futex(op=FUTEX_WAIT) scanner .

    #!/bin/bash
    #
    # Find all processes that are executing a futex(2) call with op=FUTEX_WAIT
    # In some cases this can be helpful in finding deadlock-ed processes.
    #
    
    test ! $UID -eq 0 && echo -e "WARNING: Not running as root, only processes for this user are being scanned\n" >&2;
    pids=$(ps -u $UID -opid --no-headers)
    
    for pid in $pids; do
            cat /proc/$pid/syscall |
    
            awk "{if (\$1 == 202 && \$3 == \"0x0\") {
                    print $pid
            }}";
    
            # $1 is the syscall, we compare to 202 which is the futex call
            # See: /usr/include/asm/unistd.h
    
            # $2 is the 1st param, $3 is the 2nd param, etc
            # We compare the second param to 0x0 which is FUTEX_WAIT
            # See: /usr/include/linux/futex.h
    done
    
        3
  •  -1
  •   kuriouscoder    15 年前

    UNIX保证操作系统进程永远不会陷入死锁。但是,对于用户定义的流程,没有这样的保证。据我所知,没有直接的方法可以确定一个进程是否陷入僵局。

    也就是说,你可以通过 ps -o pid,uname,command,state,stime,time . man ps 还显示了有关进程状态代码的更详细说明。