I want to create a program that:
Create child processes
List all child processes
Read PID to kill one of child processes
List all child processes again.
My code:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main(void) {
int c = 0;
printf("How many: ");
scanf("%d", & c);
int i = 0;
for (i = 1; i <= c; i++) {
pid_t pid = fork();
if (pid == 0) {
exit(0);
}
}
ListOfChildren();
int t;
printf("Kill child: ");
scanf("%d", & t);
char test[50];
snprintf(test, sizeof(test), "kill -15 %d", t);
system(test);
ListOfChildren();
return 1;
}
int ListOfChildren() {
char str[50] = "ps -o pid --ppid ";
char ppid[7];
sprintf(ppid, "%d", getpid());
strcat(str, ppid);
system(str);
return 1;
}
It creates some processes but the last process is not exist? And i can't kill
not even one... And why it shows 4 process when i want 3?
Because when you fork, your children immediately exit, this is likely that they are already dead when you try to kill them (likely, not mandatory, it depends on the scheduler). Same thing for listing: the processes you see are some of the remaining processes not yet exited and the process "ps" itself, created by your first process.
To answer your first question
The last process does not exists because, it is the child process which was forked by the system command in your program and this process is no longer valid once the command returns, hence you are not able to see the process. For more details have a look at the man page of the system command
http://linux.die.net/man/3/system
For the second question, indeed your child processes have finished executing and they have become defunct processes. you can check them in your program by executing
ps -ef | grep defunct
before you enter some option from "Kill child: ". Then you will see the child processes you forked in the program are defunct.
The reason they have become defunct is
The parent process has to explicitly take notice of
the childs demise by using the wait() system call.
http://en.linuxreviews.org/Defunct_process
You cannot kill them normally with a
kill -9 pid
That is why the "kill" does not work for you.
Related
I am working on a interactive C shell and outputting user CPU time and system CPU time of child process after executing fork. I use .tms_cutime and .tms_cstime but the output is negative. If I check using clock(), both outputs become 0s, no matter what code is run.
I got user time is -0.010000s and system time is -1400864714735.760010s.
Update: I tried to put times(&child_time_start); before fork() or wait(NULL). Both give me 0.00000s which is wrong. May I ask how to solve?
Below is the code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/times.h>
int main(void) {
struct tms child_time_start, child_time_end;
int clock_tick;
clk_tk = sysconf(_SC_CLK_TCK);
while (1){
pid_t pid = fork();
//child process
if (pid == 0){
times(&child_time_start); //start time count in child process
execlp("/bin/ls", "ls", (char *) 0);
printf("not successful");
exit(1);
}
//parent process
else{
wait(NULL);
times(&child_time_end); //end time counting
printf("child user time is %f s child system time is %f s\n", (double) (child_time_end.tms_cutime - child_time_start.tms_cutime) / clk_tk, (double) (child_time_end.tms_cstime - child_time_start.tms_cstime) / clk_tk);
}
}
return (0);
}
The child process is a copy of the parent process, but does not share its variables with it - instead, it starts with a copy of the parents variables. For that reason, the line
times(&child_time_start); //start time count in child process
must be executed by the parent process before or after the fork. If you place it between fork and if (pid==0) {, both processes will execute it, which could be useful in some cases, and it removes the time required to do the fork from the time measurement. If you place it before the fork, only the parent process will execute it but the child process gets a copy, so both have exactly the same value here.
This question already has answers here:
Create zombie process
(2 answers)
Closed 1 year ago.
my task is to create zombie process. My code looks like this:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
printf("error\n");
}
else if (pid == 0) {
printf("Child %d\n", getpid());
printf("Parents %d\n", getppid());
printf("Waiting for my Child to complete\n");
exit(0);
}
else {
sleep(5);
printf("Parent %d\n",getpid());
}
return 0;
}
When I gcc and execute the file with ./a.out I get the following output:
Child 25097
Parents 25096
Waiting for my child to complete
Parent 25096 ( a few seconds later)
My task is to create a zombie process and print out the exit-state of the child process while being in parent process. Everything is a bit confusing to me because its the first time for me using Linux and C.
Do you have some tips/ hints for me, how to solve the task? Cause I'm not sure if everything is right. I also tried playing with wait(), waitpid() and WEXITSSTATUS(), but I'm not sure about it. And I used the ps x command to check if there is a different output but I didn't notice any changes.
Thanks in advance :)
This code will successfully create a zombie process.
After the call to fork, the child prints a few lines and exits, while the parent sleeps for 5 seconds. This means you'll have a zombie process for about 5 seconds while the parent is sleeping.
When the sleep is done, the parent prints something and exits. Once the parent exits the child is inherited by the init process, which will wait for the child and make it's pid disappear fro the pid list.
You can also use wait in the parent process, in which case the child is a zombie up until the parent calls wait.
I am learning fork() in Linux, and here is my program:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 int main(void){
5 int pid;
6 pid = fork();
7 if(pid < 0){
8 exit(1);
9 }
10 if(pid == 0){
11 fork();
12 fork();
13 printf("pid:%d ppid:%d\n",getpid(),getppid());
14 exit(0);
15 }
16 else{
17 printf("parent pid:%d ppid:%d\n",getpid(),getppid());
18 exit(0);
19 }
20
21 }
Sometimes it worked fine, with result like this:
./test1.out
parent pid:27596 ppid:21425
pid:27599 ppid:27597
pid:27597 ppid:27596
pid:27598 ppid:27597
pid:27600 ppid:27598
But the result was not consistent, more often than not it worked like this:
parent pid:27566 ppid:21425
pid:27567 ppid:27566
pid:27568 ppid:27567
pid:27569 ppid:1599
pid:27570 ppid:1599
Which makes no sense to me, so I typed $ps aux to find out what process 1599 is:(with some columns deleted)
USER PID VSZ RSS STAT START COMMAND
linux 1599 63236 6316 Ss 09:03 /lib/systemd/systemd --user
Can anybody help me straighted things up?
The "inconsistency" you observed is because sometimes, the parent process(es) exited before their child process(es) terminated. So, these child processes become "orphans" as their
parent processes are not waiting for them. As a result, they are "re-parented" to the init process.
While traditionally the process id of the "init" process is 1, it's not always true. POSIX leaves it as implementation-defined:
The parent process ID of all of the existing child processes and
zombie processes of the calling process shall be set to the process ID
of an implementation-defined system process. That is, these processes
shall be inherited by a special system process.
Thus you see a particular PID as the parent (1599 in your example), which happens to be "init" process equivalent on your Linux.
The systemd is an init variant used in Debian Linux distributions - which follows a slightly more complicated implementation.
In essense, what you observed is pretty normal. Ideally, you should reap all the processes in order to avoid zombie processes.
I suppose that, sometimes, a race condition happens, and the parent dies before the child. Hence, the child becomes children from init process. In your case, that must be systemd.
Anyway, be advised that running fork(); fork(); will produce 4 processes, which is (probably) not what you intend. Use control structure as you did with the first one to have fine control on the behaviour of your program.
It is because the parent process terminates first.
In Linux there are no ophan processes. They are assigned to the init process.
If you want to control your processes so that child process terminates first, make parent process wait. Using wait() sys_call.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int pid;
int pid2;
pid = fork();
if(pid < 0){
exit(1);
}
if(pid == 0){ // child process
pid2 = fork()
if (pid2 < 0)
exit(1);
if (pid2 == 0)
{
printf("pid:%dppid:%d\n",getpid(),getppid());
exit(0);
}
wait();
printf("pid:%d ppid:%d\n",getpid(),getppid());
exit(0);
}
else{ // parent process
wait();
printf("parent pid:%d ppid:%d\n",getpid(),getppid());
exit(0);
}
return 0;
}
systemd is an init system used in Linux distributions to bootstrap the
user space and manage all processes subsequently
I am interested in creating a zombie process. To my understanding, zombie process happens when the parent process exits before the children process. However, I tried to recreate the zombie process using the following code:
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
pid_t child_pid;
child_pid = fork ();
if (child_pid > 0) {
exit(0);
}
else {
sleep(100);
exit (0);
}
return 0;
}
However, this code exits right after execute which is expected. However, as I do
ps aux | grep a.out
I found a.out is just running as a normal process, rather than a zombie process as I expected.
The OS I am using is ubuntu 14.04 64 bit
Quoting:
To my understanding, zombie process happens when the parent process exits before the children process.
This is wrong. According to man 2 wait (see NOTES) :
A child that terminates, but has not been waited for becomes a "zombie".
So, if you want to create a zombie process, after the fork(2), the child-process should exit(), and the parent-process should sleep() before exiting, giving you time to observe the output of ps(1).
For instance, you can use the code below instead of yours, and use ps(1) while sleep()ing:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
int status;
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
/* Child */
if (pid == 0)
exit(0);
/* Parent
* Gives you time to observe the zombie using ps(1) ... */
sleep(100);
/* ... and after that, parent wait(2)s its child's
* exit status, and prints a relevant message. */
pid = wait(&status);
if (WIFEXITED(status))
fprintf(stderr, "\n\t[%d]\tProcess %d exited with status %d.\n",
(int) getpid(), pid, WEXITSTATUS(status));
return 0;
}
A zombie or a "defunct process" in Linux is a process that has been completed, but its entry still remains in the process table due to lack of correspondence between the parent and child processes. Usually, a parent process keeps a check on the status of its child processes through the wait() function. When the child process has finished, the wait function signals the parent to completely exit the process from the memory. However, if the parent fails to call the wait function for any of its children, the child process remains alive in the system as a dead or zombie process. These zombie processes might accumulate, in large numbers, on your system and affect its performance.
Below is a c program to creating a Zombie-Process on our system Save this file as zombie.c:
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
pid_t child_pid;
child_pid = fork ();
if (child_pid > 0) {
sleep (60);
}
else {
exit (0);
}
return 0;
}
The zombie process created through this code will run for 60 seconds. You can increase the time duration by specifying a time(in seconds) in the sleep() function.
Compile this program
gcc zombie.c
Now run the zombie program:
./a.out
The ps command will now also show this defunct process, open a new terminal and use the below command to check the defunct process:
aamir#aamir:~/process$ ps -ef | grep a.out
aamir 10171 3052 0 17:12 pts/0 00:00:00 ./a.out
aamir 10172 10171 0 17:12 pts/0 00:00:00 [a.out] <defunct> #Zombie process
aamir 10177 3096 0 17:12 pts/2 00:00:00 grep --color=auto a.out
May be it look childish for most of you but I am unable to understand this small piece of code.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char** argv) {
int i, pid;
pid = fork();
printf("Forking the pid: %d\n",pid);
for(i =0; i<5; i++)
printf("%d %d\n", i,getpid());
if(pid)
wait(NULL);
return (0);
}
Out put of this program is
Forking the pid: 2223
0 2221
1 2221
2 2221
3 2221
4 2221
Forking the pid: 0
0 2223
1 2223
2 2223
3 2223
4 2223
Press [Enter] to close the terminal ...
In the for loop the printf command is used once. Why "Forking the pid" and after that the pid's are printed twice. How this is working? Can anybody explain me this? Thanks in advance.
Can anybody explain me why we have to use wait here? What I understood from the man pages is wait retuns the control to parent process? Is what I understood is correct?Is it necessary to use wait after forking a process?
Operating system : ubuntu, compiler : gcc, IDE : netbeans
But that' exactly what fork does. You forked the process and everything after the fork is done twice because now you have two processes executing the same printing code. You are basically asking why fork forks. fork forks because is is supposed to fork. That's what it's for.
After fork the parent and the child processes are generally executed in parallel, meaning that the nice sequential output you see in your example is not guaranteed. You might have easily ended up with line-interleaved output from two processes.
wait function in your case is executed from the parent process only. It makes it wait until the child process terminates, and only after that the parent process proceeds to terminate as well. Calling wait in this particular example is not really critical, since the program does nothing after that, it just terminates. But, for example, if you wanted to receive some feedback from the child process into the parent process and do some additional work on that feedback in the parent process, you'd have to use wait to wait for the child process to complete its execution.
The fork() call makes a new process. The rest of the code is then executed from each of the 2 processes. (Man page)
You're printing in both processes. Put your printing loop in an else clause of the if (pid):
pid = fork();
if(pid)
{
printf("Child pid: %d\n",pid);
wait(NULL);
}
else
{
for(i =0; i<5; i++)
printf("%d %d\n", i,getpid());
}
You see, fork returns twice, once in the parent process and once in the child process. It returns 0 in the child and the pid of the created process in the parent.
Because both the parent and child process are outputting their results.
See here: http://en.wikipedia.org/wiki/Fork_(operating_system)#Example_in_C for a good example.
fork creates a new process, and returns in both the old process (the parent) and in the new process (the child).
You can tell which one you are in by looking at the return value from fork. In the parent process it returns the PID of the child process. In the child process it return 0.