Haris_tech
Haris_tech

Reputation: 83

fork() and kill in linux

In my project, I need a sub-task to play in parallel with a parent task. I use fork() to create a parallel process which is aplay xyz.wav. Now when I want to kill the child process from the parent process e.g system("kill -9 aplay ") the aplay is killed, but I see two instances of the parent task. I think one of them is a copy made by the call to fork() and the other one is the original. And with each fork() call, the number of copies increases. I am conscious about memory overflow. I just want to keep the original process. I have tried to kill that parent copy but failed!copies of the parent process appear as 'defunct'.

the 'defucnt' process continue to increase as i call parallel process, whether i kill aplay or not. I also tried to kill defunt by its PID, it also didn't work.

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

i also tried with this in test() command

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

by doing this only one parent process remain after aplay finishes to play sound, no matter how many times i call the "test" command. but the issue with this is that, I can not type any other command during sound play, until it finishes. so could not kill it in between playing the sound.

I want to play sound in parallel, and want to kill any time i want.

Upvotes: 2

Views: 4317

Answers (1)

paxdiablo
paxdiablo

Reputation: 881383

Don't kill it that way! You have the child PID in pid1, just use the kill() function to kill it.

Spawning an separate process to run killall is unnecessary, expensive and (as you've found out), not that reliable. What if there are five copies of that executable running?

You can use something like:

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

in your parent.

I would also seriously look into removing the system calls in the child process as well since they start up separate processes. You can do better by using the exec family of calls the replace the program in the child's process space.

Upvotes: 6

Related Questions