What are processes and threads?
- A process is simply an abstraction of a running program.
- Processes include a set of resources such as open files
and pending signals, internal kernel data, processor state, an address space,
one or more threads of execution, and a data section containing global variables.
Whereas,
- Threads are the units of execution within a program.
- In Linux Operating system, the scheduling of thread or processes take place with a common concept of tasks--
A Linux Scheduler will schedule tasks and these tasks could be
1. a single-threaded process (e.g. created by fork function without any thread library)
2. any thread inside a multi-threaded process (including its main thread)
3.kernel tasks, which are started internally in the kernel and stay in kernel space (e.g kworke, kswapd . etc...)
- Each thread within a process has a 1. unique program counter, 2. process stack, 3. and set of processor registers.
- Threads are light weight. They don't have their own memory spaces and other resources unlike processes. All processes start with a single thread. So they behave like lightweight processes but are always tied to a parent "thick" process. So, creating a new process is a slightly heavy task and involves allocating all these resources while cresting a thread does not. Killing a process also involves releasing all these resources while a thread does not. However, killing a thread's parent process releases all resources of the thread.
- A process is suspended by itself and resumed by itself. Same with a thread but if a thread's parent process is suspended then the threads are all suspended.
- In Linux, a process is created by means of the fork() system call, which creates a new process by duplicating an existing one.
- The new process is an exact copy of the old process. (Now, a question might come immediately to our mind- who creates the first process?? The first process is the init process which is literally created from scratch during booting).
- The process that calls fork() is the parent, whereas the new process is the child. The parent resumes execution and the child starts execution at the same place, where the call returns. The fork() system call returns from the kernel twice: once in the parent process and again in the newborn child(see the below diagram).
fork()
- The fork() function is used to create a new process by duplicating the existing process from which it is called.
- The existing process from which this function is called becomes the parent process and the newly created process becomes the child process.
- Inside the newly created address space exec*() family of function calls is used to create a new address space and load a new program into it. In modern Linux kernels, fork() is actually implemented via the clone() system call,
- Finally, a program exits via the exit() system call. This function terminates the process and frees all its resources.
- Fork is the only mechanism to create new process, any other mechanism will inherently use fork inside.
- A parent process can inquire about the status of a terminated child via the wait4()system call, which enables a process to wait for the termination of a specific process.
- The child is a duplicate copy of the parent but there are some exceptions to it.
- The child has a unique PID like any other process running in the operating system.
- The child has a parent process ID which is same as the PID of the process that created it.
- Resource utilization and CPU time counters are reset to zero in child process.
- Set of pending signals in child is empty.
- Child does not inherit any timers from its parent
- The child does not inherit its parent's memory locks (mlock(2), mlockall(2))
- The child does not inherit outstanding asynchronous I/O operations from its parent.
What is the return value of fork()?
- If the fork() function is successful then it returns twice.
- Once it returns in the child process with return value zero and then it returns in the parent process with child’s PID as return value.
- This behavior is because of the fact that once the fork is called, child process is created and since the child process shares the text segment with parent process and continues execution from the next statement in the same text segment so fork returns twice (once in parent and once in child).
fork() in action |
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t pid;
char *message;
int n;
printf("fork program is starting\n");
pid = fork();
switch(pid)
{
case -1:
perror("fork failed");
exit(1);
case 0:
message = "This is the child";
n = 5;
break;
default:
message = "This is the parent";
n = 3;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);
}
exit(0);
}
The parent gets over before the child so we can see the shell prompt appears mixed with the output of child process.
Now, lets try to finish the child process first.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t pid;
char *message;
int n;
printf("fork program starting\n");
pid = fork();
switch(pid)
{
case -1:
perror("fork failed");
exit(1);
case 0:
message = "This is the child";
n = 3;
break;
default:
message = "This is the parent";
n = 5;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);
}
exit(0);
}
When the child process is over, its association with the parent is not finished. The association remains until the parent calls the wait system call or the parent survives normally. Till this association remains after the child process is over the child process is called as a zombie process( the last ritual hasn't been performed till now).
NB: when the parent terminates but the child is still running then it is running as an orphan process.
Waiting for the child--->
A parent can wait for its child by calling wait system call. This call returns the child's PID as return value.
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t pid;
char *message;
int n;
int exit_code;
printf("fork program starting\n");
pid = fork();
switch(pid)
{
case -1:
exit(1);
case 0:
message = "This is the child";
n = 5;
exit_code = 37;
break;
default:
message = "This is the parent";
n = 3;
exit_code = 0;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);
}
/* This section of the program waits for the child process to finish. */
if(pid) {
int stat_val;
pid_t child_pid;
child_pid = wait(&stat_val);
printf("Child has finished: PID = %d\n", child_pid);
if(WIFEXITED(stat_val))
printf("Child exited with code %d\n", WEXITSTATUS(stat_val));
else
printf("Child terminated abnormally\n");
}
exit (exit_code);
}
fork() vs vfork() vs exec() vs system() vs clone()
Let us first see the standard definition of these system calls.
Fork : The fork call is used to duplicate the current process, the new process identical in almost every way except that it has its own PID. The return value of the function fork distinguishes the two processes, zero is returned in the child and PID of child in parent process.
Exec :The exec call is a way to basically replace the entire current process with a new program. It loads the program into the current process space and runs it from the entry point. As a new process is not created, the process identifier (PID) does not change, but the machine code, data, heap, and stack of the process are replaced by those of the new program.exec() replaces the current process with a the executable pointed by the function. Control never returns to the original program unless there is an exec() error. exec system call can be executed as execl, execlp, execle, execv, execvp, execvpe
Vfork: The basic difference between vfork and fork is that when a new process is created with vfork(), the parent process is temporarily suspended, and the child process might borrow the parent's address space. This strange state of affairs continues until the child process either exits, or calls execve(), at which point the parent process continues.
Vfork: The basic difference between vfork and fork is that when a new process is created with vfork(), the parent process is temporarily suspended, and the child process might borrow the parent's address space. This strange state of affairs continues until the child process either exits, or calls execve(), at which point the parent process continues.
This means that the child process of a vfork() must be careful to avoid unexpectedly modifying variables of the parent process. In particular, the child process must not return from the function containing the vfork() call, and it must not call exit() (if it needs to exit, it should use _exit(); actually, this is also true for the child of a normal fork()).
The intent of
vfork
was to eliminate the overhead of copying the whole process image if you only want to do an exec*
in the child. Because exec*
replaces the whole image of the child process, there is no point in copying the image of the parent.if ((pid = vfork()) == 0) {
execl(..., NULL); /* after a successful execl the parent should be resumed */
_exit(127); /* terminate the child in case execl fails */
}
For other kinds of uses, vfork is dangerous and unpredictable.
With most current kernels, however, including Linux, the primary benefit of vfork has disappeared because of the way fork is implemented. Rather than copying the whole image when fork is executed, copy-on-write techniques are used.
Clone : Clone, as fork, creates a new process. Unlike fork, these calls allow the child process to share parts of its execution context with the calling process, such as the memory space, the table of file descriptors, and the table of signal handlers.
When the child process is created with clone, it executes the function application fn(arg). (This differs from fork, where execution continues in the child from the point of the original fork call.) The fn argument is a pointer to a function that is called by the child process at the beginning of its execution. The arg argument is passed to the fn function.
When the fn(arg) function application returns, the child process terminates. The integer returned by fn is the exit code for the child process. The child process may also terminate explicitly by calling exit(2) or after receiving a fatal signal.
System : The system() library function uses fork(2) to create a child process that executes the shell command specified in command using execl(3) as follows: execl("/bin/sh", "sh", "-c", command, (char *) 0); system() returns after the command has been completed.During execution of the command , SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored, in the process that calls system() (these signals will be handled according to their defaults inside the child process that executes command). If command is NULL, then system() returns a status indicating whether a shell is available on the system
- In situations where performance is critical and/or memory limited,
vfork
+exec*
can therefore be a good alternative tofork
+exec*
. The problem is that it is less safe and the man page saysvfork
is likely to become deprecated in the future. - Because memory page tables are not duplicated,
vfork
is much faster thanfork
andvfork
's execution time is not affected by the amount of memory the parent process uses - system() will invoke your systems default command shell, which will execute the command string passed as an argument, that itself may or may not create further processes, that would depend on the command and the system. Either way, at least a command shell process will be created.
- With system() you can invoke any command, whereas with exec(), you can only invoke an executable file. Shell scripts and batch files must be executed by the command shell.
Great blog here! Additionalkly your web site lots up fast!
ReplyDeleteWhat host are you using? Caan I am gettting
your associate hyperlink on your host? I desire my site loaded up as fast ass yours lol
My website peer2peer Software
I was more than happy to uncover this site. I need to too thank you for youyr time for this wonderfull read!!
ReplyDeleteI definitely appreciated every little bitt of it and i
also have you book marked to see new information in your blog.
Feell free to surf to my web page; bse sensex 30 -
,
I am not sure where you're getting yolur information, but good
ReplyDeletetopic. I needs to spend some time learning much more or understanding more.
Thanks for magnificent info I waas looking ffor this
information for my mission.
Revieew my web site :: project management app
Good day! I know this is kina off topic but I was wondering
ReplyDeleteif you knew where I could locate a captcha plugin for my comment
form? I'm using the same blog platform as yours and I'm having difficulty finding one?
Thanks a lot!
myweb-site ... free wallpapers download
I'm not sure where you are getting your information, but good topic.
ReplyDeleteI needs to spend some time learning more or understanding more.
Thanks for great information I was looking for this
info ffor my mission.
my blog :: room wallpaper ()
Nice blog pkj :)
ReplyDeleteFantastic articles is post by you in this blog. You give a nice thing. Thank you for such a nice article. Every word of this blog helps me to give detail to me.
ReplyDeleteVisit: Data Analytics
fastastic articles follow back http://categorythemes.blogspot.co.id/2016/01/collection-wordpress-theme.html thnks
ReplyDeleteThank you very much,nice article.
ReplyDeleteIs process & thread are same in the linux point of view or different???
ReplyDeleteIs that parent PID & child PID are same (or) different??
ReplyDeleteFor example one parent created a child, is there any possible to child became a parent??
If child became a parent, what is the status of the original parent??
It’s always so sweet and also full of a lot of fun for me personally and my office colleagues to search you blog a minimum of thrice in a week to see the new guidance you have got.
ReplyDeletenebosh course in chennai
safety course in chennai
Good article
ReplyDeleteGood Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.Linux Online Training
ReplyDeleteThanks for sharing the valuable information. it’s really helpful.
ReplyDeleteMEAN Stack Online Training
Thanks for the greate post, you have my admirations!
ReplyDeleteProbably people hope to see an update on this Linux topic.
P.S. Only 1 software ninja can kill another software ninja!
Software
Delasport
I felt very happy while reading this site. This was really very informative site for me. I really liked it. This was really a cordial post. Thanks a lot!.
ReplyDeleterenovlies behang
This comment has been removed by the author.
ReplyDeleteThey don't have their own memories and other resources. All threads start with a single thread and are always tied to a thick process. Creating a new thread is a slightly heavy task. Allocating all these resources while crested a thread doesn't involve any resource allocation. Killing a process also involves releasing these resources while a thread doesn't release them. However, killing a thread's parents process releases all resources of that thread.
ReplyDeletelathe machine