C 如何杀死僵尸进程?

C 如何杀死僵尸进程?,c,macos,terminal,zombie-process,C,Macos,Terminal,Zombie Process,我有两个问题:我制作的一个程序出现了故障,并产生了几乎无法解决的过程,如果其中一个子问题得到解决,我相信这两个问题都会很容易解决。我正在OSX 10.6.8上运行2008年初的Macbook /问题1,编码:/ 我一直在使用termios.h I/O来创建iRobot。我编译时没有警告或错误,可以顺利运行程序。我通过usb连接到机器人,这解释了输入“/dev/tty.usbserial” 程序首先检查给定的参数,然后尝试使用bisconnect()函数连接给定的参数(char*device is

我有两个问题:我制作的一个程序出现了故障,并产生了几乎无法解决的过程,如果其中一个子问题得到解决,我相信这两个问题都会很容易解决。我正在OSX 10.6.8上运行2008年初的Macbook

/问题1,编码:/

我一直在使用termios.h I/O来创建iRobot。我编译时没有警告或错误,可以顺利运行程序。我通过usb连接到机器人,这解释了输入“/dev/tty.usbserial”

程序首先检查给定的参数,然后尝试使用bisconnect()函数连接给定的参数(char*device is/dev/tty.usbserial)。它在我的mac电脑上失败了

//in file simple.c:
int main(int argc, char *argv[]){
if(argc!=2){
    printf("Put port... like /dev/tty.usbserial or something\n");
    exit(EXIT_FAILURE);
}
printf("Starting...\n");
biscConnect(argv[1]);
}
void biscConnect(char *device){
struct termios tty;

// Try to open the device from the input
    if((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK))==-1){
        fprintf(stderr, "Serial port at %s could not be opened: %s\n", device, strerror(errno));
        exit(EXIT_FAILURE);
    }
     tcflush (fd, TCIOFLUSH);
     tcgetattr(fd, &tty);
     tty.c_iflag     = IGNBRK | IGNPAR;
     tty.c_lflag     = 0;
     tty.c_oflag     = 0;
     tty.c_cflag     = CREAD | CS8 | CLOCAL;
     cfsetispeed(&tty, B57600);
     cfsetospeed(&tty, B57600);
     tcsetattr(fd, TCSANOW, &tty);

     //The code fails prior to this point
}
然后我会发送字节给机器人,让它移动,如果它在此之前没有被卡住的话

/问题#2,无法解决的流程:/ 当我运行文件时,终端进入一种奇怪的模式,提示消失了,我可以键入任何我想要的内容(通常表示进程正在运行)。我无法使用control-c退出。我似乎唯一能退出的方法就是关闭终端窗口。这无法终止正在运行的进程

我可以很容易地查找pid,但是活动监视器,但是强制退出无法终止进程,kill-9[pid]失败,killall[program name]失败,等等。尽管确认了程序的存在。强制终止进程的唯一方法似乎是物理上关闭计算机的电源并重新启动它(即关机不起作用,因为它试图终止进程,但失败了)。如果要调试程序,每次运行时都需要重启笔记本电脑,那我就浪费了大量时间!我可以不断创建更多进程,但无法删除它们

我想如果我知道父进程,我可能会杀死这些“僵尸”进程,但我不知道父进程是什么


任何关于如何在不进行电源循环的情况下摆脱这些进程的想法都将是巨大的帮助,谢谢

你可以通过运行
ps-ef
或使用
htop
来找出是谁制造了这个不死进程

PID   TTY      STAT   TIME COMMAND
21138 tty1     T      0:00 sudo /usr/bin/aura -Akax open_watcom openwatcom-extras-hg HOME=/home/hav3lock USER=hav3lock SHELL=/bin/zsh TERM=linux PATH=/usr/local/sbin:/u
21139 tty1     T      0:00  \_ /usr/bin/aura -Akax open_watcom openwatcom-extras-hg TERM=linux PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/
22111 tty1     Z      0:00      \_ [su] <defunct>`

通过运行
ps-ef
或使用
htop
,您可以找出是谁诞生了这个不死进程

PID   TTY      STAT   TIME COMMAND
21138 tty1     T      0:00 sudo /usr/bin/aura -Akax open_watcom openwatcom-extras-hg HOME=/home/hav3lock USER=hav3lock SHELL=/bin/zsh TERM=linux PATH=/usr/local/sbin:/u
21139 tty1     T      0:00  \_ /usr/bin/aura -Akax open_watcom openwatcom-extras-hg TERM=linux PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/
22111 tty1     Z      0:00      \_ [su] <defunct>`

在Mac OS X 10.8.4上,我从
zombie.c
创建了一个程序
zombie

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    pid_t pid;

    if ((pid = fork()) >= 0)
    {
        if (pid == 0)
        {
            printf("%d: committing suicide (parent %d)\n", (int)getpid(), (int)getppid());
            exit(0);
        }
        else
        {
            printf("%d: going to sleep for a while - child %d might die while I snooze\n",
                (int)getpid(), (int)pid);
            sleep(30);
            printf("%d: awake\n", (int)getpid());
        }
    }
    return 0;
}
在另一个终端窗口中,运行
ps-f
生成:

  UID   PID  PPID   C STIME   TTY           TIME CMD
  503   260   249   0 12:42PM ttys004    0:00.08 -bash
  503  2443   260   0  5:11PM ttys004    0:00.00 ./zombie
  503  2444  2443   0  5:11PM ttys004    0:00.00 (zombie)
括号中的
(zombie)
是已失效的进程,括号中的名称是进程的原始名称。当我将程序复制到
活死人
时,相应的输出是:

$ ./zombie
2443: going to sleep for a while - child 2444 might die while I snooze
2444: committing suicide (parent 2443)
2443: awake
$
  UID   PID  PPID   C STIME   TTY           TIME CMD
  503   260   249   0 12:42PM ttys004    0:00.09 -bash
  503  2454   260   0  5:13PM ttys004    0:00.00 ./living-dead
  503  2455  2454   0  5:13PM ttys004    0:00.00 (living-dead)
(在大多数系统上,失效的进程被标记为
或类似的东西。)


显然,
PPID
列中的值标识了僵尸的父进程,并且各种进程ID与程序本身的输出相匹配。

在Mac OS X 10.8.4上,我从
zombie.c
创建了一个程序
zombie

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    pid_t pid;

    if ((pid = fork()) >= 0)
    {
        if (pid == 0)
        {
            printf("%d: committing suicide (parent %d)\n", (int)getpid(), (int)getppid());
            exit(0);
        }
        else
        {
            printf("%d: going to sleep for a while - child %d might die while I snooze\n",
                (int)getpid(), (int)pid);
            sleep(30);
            printf("%d: awake\n", (int)getpid());
        }
    }
    return 0;
}
在另一个终端窗口中,运行
ps-f
生成:

  UID   PID  PPID   C STIME   TTY           TIME CMD
  503   260   249   0 12:42PM ttys004    0:00.08 -bash
  503  2443   260   0  5:11PM ttys004    0:00.00 ./zombie
  503  2444  2443   0  5:11PM ttys004    0:00.00 (zombie)
括号中的
(zombie)
是已失效的进程,括号中的名称是进程的原始名称。当我将程序复制到
活死人
时,相应的输出是:

$ ./zombie
2443: going to sleep for a while - child 2444 might die while I snooze
2444: committing suicide (parent 2443)
2443: awake
$
  UID   PID  PPID   C STIME   TTY           TIME CMD
  503   260   249   0 12:42PM ttys004    0:00.09 -bash
  503  2454   260   0  5:13PM ttys004    0:00.00 ./living-dead
  503  2455  2454   0  5:13PM ttys004    0:00.00 (living-dead)
(在大多数系统上,失效的进程被标记为
或类似的东西。)



显然,
PPID
列中的值标识了僵尸的父进程,并且各种进程ID与程序本身的输出相匹配。

你不能杀死僵尸;他们是不死生物。你可以杀死僵尸的父进程,在这种情况下,僵尸会被init进程继承,这会迅速让他们摆脱痛苦。@JonathanLeffler:僵尸不会定期收割吗?@JonathanLeffler:我明白了,那么有可能杀死父进程,然后杀死子进程吗?问题是我不知道父母是谁。请看这里关于如何与僵尸战斗的可能解决方案:@mvp:好的,这很有帮助。请发布一个答案,这样我可以选择你作为最佳答案。你不能杀死僵尸;他们是不死生物。你可以杀死僵尸的父进程,在这种情况下,僵尸会被init进程继承,这会迅速让他们摆脱痛苦。@JonathanLeffler:僵尸不会定期收割吗?@JonathanLeffler:我明白了,那么有可能杀死父进程,然后杀死子进程吗?问题是我不知道家长是谁。请看这里关于如何对抗僵尸的可能解决方案:@mvp:好的,这很有帮助,请发布一个答案,这样我可以选择你作为最佳答案。注意,我在这篇文章中使用了
ps ef
;非
htop
。另外,我应该注意到我在用sudo运行ps-ef。杀死21138可能会也可能不会杀死21139,而僵尸在21138死之前不会离开。好的,我得到这个:501 1507 1 0 0:00.00??0:00.01./simple/dev/tty.usbserial但这有什么帮助?它似乎不给父母;它只是承认它的存在。因此,要找到给定僵尸的父级,只需运行:
sudo ps ef | sudo awk'{print$1”\t“$2”\t“$3”\t“$5”$6”}grep-w Z--before context=20
,并确保相应地调整--before context。您可以用
-wz
交换您要查找的父级僵尸的进程id。(试图编辑我以前的评论,所以抱怨。)注意,我在这篇文章中使用了
ps-ef
;非
htop
。另外,我应该注意到我在用sudo运行ps-ef。杀死21138可能会也可能不会杀死21139,而僵尸在21138死之前不会离开。好的,我得到这个:501 1507 1 0 0:00.00??0:00.01./simple/dev/tty.usbserial但这有什么帮助?它似乎不给父母;它只是承认它的存在。所以要找到给定僵尸的父级,只需运行:
sudo ps ef | sudo awk'{print$1”\t“$2”\t“$3”\t“$5”$6”}| grep-w Z--before context=20