【问题标题】:fork() and kill in linuxlinux中的fork()和kill
【发布时间】:2012-08-29 20:37:25
【问题描述】:

在我的项目中,我需要一个子任务与父任务并行播放。我使用 fork() 创建一个并行进程,即aplay xyz.wav。现在,当我想从父进程中杀死子进程时,例如system("kill -9 aplay ") aplay 被杀死了,但是我看到了父任务的两个实例。我认为其中一个是通过调用 fork() 制作的副本,另一个是原件。并且随着每次 fork() 调用,副本的数量都会增加。我意识到内存溢出。我只想保留原来的过程。我试图杀死该父副本但失败了!父进程的副本显示为“已失效”。

'defucnt' 进程在我调用并行进程时继续增加,无论我是否终止 aplay。我也试图通过它的 PID 杀死 defunt,它也没有工作。

static int
 test(Core *pc, char *args)
{


pid1=fork();
if (pid1 ==0)
{  
        system ("ps " );
       system("aplay /opt/Line_Tone_14s.wav");

      _exit(0);
}
else if(pid1<0)
{
 out("fork() ERROR (-1) returned\n");
}
else if(pid1>0)
{
 out("I AM IN PARENT PROCESS() NOW\n");
 }
return 1;

 }

static int
test1(Core *pc, char *args)
{ 
 system ("ps " );
system ("killall -9 aplay "); 
return 1;

}

    Initially 

> PID TTY          TIME CMD
1580 pts/0    00:00:00 sudo
1581 pts/0    00:00:00 su
1589 pts/0    00:00:00 bash
5732 pts/0    00:00:00 parent
5738 pts/0    00:00:00 sh
5739 pts/0    00:00:00 ps

>test
> PID TTY          TIME CMD
1580 pts/0    00:00:00 sudo
1581 pts/0    00:00:00 su
1589 pts/0    00:00:00 bash
5732 pts/0    00:00:00 parent
5737 pts/0    00:00:00 parent
5740 pts/0    00:00:00 sh
5741 pts/0    00:00:00 aplay
5743 pts/0    00:00:00 sh
5744 pts/0    00:00:00 ps


>test1                  
>killed

after kill
>PID TTY          TIME CMD
1580 pts/0    00:00:00 sudo
1581 pts/0    00:00:00 su
1589 pts/0    00:00:00 bash
5732 pts/0    00:00:00 parent
5737 pts/0    00:00:00 parent <defunct>
5753 pts/0    00:00:00 sh
5754 pts/0    00:00:00 ps

>test
> PID TTY          TIME CMD
1580 pts/0    00:00:00 sudo
1581 pts/0    00:00:00 su
1589 pts/0    00:00:00 bash
5732 pts/0    00:00:00 parent
5737 pts/0    00:00:00 parent <defunct>
5759 pts/0    00:00:00 parent
5762 pts/0    00:00:00 sh
5763 pts/0    00:00:00 aplay
5765 pts/0    00:00:00 sh
5766 pts/0    00:00:00 ps

>test1
>killed

after kill

>PID TTY          TIME CMD
 1580 pts/0    00:00:00 sudo
1581 pts/0    00:00:00 su
1589 pts/0    00:00:00 bash
 5732 pts/0    00:00:00 parent
5737 pts/0    00:00:00 parent <defunct>
5759 pts/0    00:00:00 parent <defunct>
5773 pts/0    00:00:00 sh
5774 pts/0    00:00:00 ps

我也在 test() 命令中尝试过这个

else if(pid1>0)
 {
  out("I AM IN PARENT PROCESS() NOW\n");
 wait(&status);
 }

通过这样做,在 aplay 完成播放声音后,无论我调用多少次“测试”命令,都只剩下一个父进程。但问题是,在声音播放过程中,我无法输入任何其他命令,直到完成。所以无法在播放声音之间杀死它。

我想并行播放声音,并且想随时杀死。

【问题讨论】:

    标签: c linux parallel-processing fork kill-process


    【解决方案1】:

    不要那样杀死它! pid1 中有子 PID,只需使用 kill() 函数杀死它。

    生成一个单独的进程来运行killall 是不必要的、昂贵的并且(正如您所发现的那样)并不那么可靠。如果该可执行文件有 5 个 个副本在运行怎么办?

    你可以使用类似的东西:

    #include <sys/types.h>
    #include <signal.h>
    :
    int rc = kill (pid1, 9);  // or SIGKILL for portability, rather than 9.
    // Check rc and errno.
    

    在你的父母中。

    我也会认真考虑删除子进程中的 system 调用,因为它们会启动单独的进程。您可以通过使用exec 系列调用替换子进程空间中的程序来做得更好。

    【讨论】:

    • 我会使用 SIGKILL 而不是 9... :-) 但无论如何 +1,简单明了。
    • 点了,@R..,将其添加为评论。
    • @Haris_tech,您仍在使用system 运行游戏。这将导致一个孩子和孙子,你只能杀死孩子。摆脱系统并使用exec,那么只会有一个孩子。而且,你的编辑是正确的,你不能杀死过时的进程,它们已经死了。你只需要等待他们。这样做的方法是捕获 SIGCHLD 信号然后等待。但首先,放弃系统调用。
    猜你喜欢
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多