Tuesday, December 20, 2011

Forking vs Threading

So, finally after long time, i am able to figure out the difference between forking and threading :)
When i have been surfing around, i see a lots of threads/questions regarding forking and threading, lots of queries which one should be used in the applications. So i wrote this post which could clarify the difference between these two based on which you could decide what you want to use in your application/scripts.

What is Fork/Forking:
Fork is nothing but a new process that looks exactly like the old or the parent process but still it is a different process with different process ID and having  it’s own memory. Parent process creates a separate address space for child. Both parent and child process possess the same code segment, but execute independently from each other.

The simplest example of forking is when you run a command on shell in unix/linux. Each time a user issues a command, the shell forks a child process and the task is done.
When a fork system call is issued, a copy of all the pages corresponding to the parent process is created, loaded into a separate memory location by the OS for the child process, but in certain cases, this is not needed. Like in ‘exec’ system calls, there is not need to copy the parent process pages, as execv replaces the address space of the parent process itself.

Few things to note about forking are:
The child process will be having it’s own unique process ID.
The child process shall have it’s own copy of parent’s file descriptor.
File locks set by parent process shall not be inherited by child process.
Any semaphores that are open in the parent process shall also be open in the child process.
Child process shall have it’s own copy of message queue descriptors of the parents.
Child will have it’s own address space and memory.
Fork is universally accepted than thread because of the following reasons:Development is much easier on fork based implementations.
Fork based code a more maintainable.
Forking is much safer and more secure because each forked process runs in its own virtual address space. If one process crashes or has a buffer overrun, it does not affect any other process at all.
Threads code is much harder to debug than fork.
Fork are more portable than threads.
Forking is faster than threading on single cpu as there are no locking over-heads or context switching.
Some of the applications in which forking is used are: telnetd(freebsd), vsftpd, proftpd, Apache13, Apache2, thttpd, PostgreSQL.

Pitfalls in Fork:- In fork, every new process should have it’s own memory/address space, hence a longer startup and stopping time.
- If you fork, you have two independent processes which need to talk to each other in some way. This inter-process communication is really costly.
- When the parent exits before the forked child, you will get a ghost process. That is all much easier with a thread. You can end, suspend and resume threads from the parent easily. And if your parent exits suddenly the thread will be ended automatically.
- In-sufficient storage space could lead the fork system to fail.
What are Threads/Threading:Threads are Light Weight Processes (LWPs). Traditionally, a thread is just a CPU (and some other minimal state) state with the process containing the remains (data, stack, I/O, signals). Threads require less overhead than “forking” or spawning a new process because the system does not initialize a new system virtual memory space and environment for the process. While most effective on a multiprocessor system where the process flow can be scheduled to run on another processor thus gaining speed through parallel or distributed processing, gains are also found on uniprocessor systems which exploit latency in I/O and other system functions which may halt process execution.

Threads in the same process share:Process instructions
Most data
open files (descriptors)
signals and signal handlers
current working directory
User and group id

Each thread has a unique:
Thread ID
set of registers, stack pointer
stack for local variables, return addresses
signal mask
priority
Return value: errno
Few things to note about threading are:Thread are most effective on multi-processor or multi-core systems.
For thread – only one process/thread table and one scheduler is needed.
All threads within a process share the same address space.
A thread does not maintain a list of created threads, nor does it know the thread that created it.
Threads reduce overhead by sharing fundamental parts.
Threads are more effective in memory management because they uses the same memory block of the parent instead of creating new.

Pitfalls in threads:
Race conditions: The big loss with threads is that there is no natural protection from having multiple threads working on the same data at the same time without knowing that others are messing with it. This is called race condition. While the code may appear on the screen in the order you wish the code to execute, threads are scheduled by the operating system and are executed at random. It cannot be assumed that threads are executed in the order they are created. They may also execute at different speeds. When threads are executing (racing to complete) they may give unexpected results (race condition). Mutexes and joins must be utilized to achieve a predictable execution order and outcome.
Thread safe code: The threaded routines must call functions which are “thread safe”. This means that there are no static or global variables which other threads may clobber or read assuming single threaded operation. If static or global variables are used then mutexes must be applied or the functions must be re-written to avoid the use of these variables. In C, local variables are dynamically allocated on the stack. Therefore, any function that does not use static data or other shared resources is thread-safe. Thread-unsafe functions may be used by only one thread at a time in a program and the uniqueness of the thread must be ensured. Many non-reentrant functions return a pointer to static data. This can be avoided by returning dynamically allocated data or using caller-provided storage. An example of a non-thread safe function is strtok which is also not re-entrant. The “thread safe” version is the re-entrant version strtok_r.
Advantages in threads:Threads share the same memory space hence sharing data between them is really faster means inter-process communication (IPC) is real fast.
If properly designed and implemented threads give you more speed because there aint any process level context switching in a multi threaded application.
Threads are really fast to start and terminate.
Some of the applications in which threading is used are: MySQL, Firebird, Apache2, MySQL 323

FAQs:1. Which should i use in my application ?
Ans: That depends on a lot of factors. Forking is more heavy-weight than threading, and have a higher startup and shutdown cost. Interprocess communication (IPC) is also harder and slower than interthread communication. Actually threads really win the race when it comes to inter communication. Conversely, whereas if a thread crashes, it takes down all of the other threads in the process, and if a thread has a buffer overrun, it opens up a security hole in all of the threads.
which would share the same address space with the parent process and they only needed a reduced context switch, which would make the context switch more efficient.

2. Which one is better, threading or forking ?
Ans: That is something which totally depends on what you are looking for. Still to answer, In a contemporary Linux (2.6.x) there is not much difference in performance between a context switch of a process/forking compared to a thread (only the MMU stuff is additional for the thread). There is the issue with the shared address space, which means that a faulty pointer in a thread can corrupt memory of the parent process or another thread within the same address space.

3. What kinds of things should be threaded or multitasked?
Ans: If you are a programmer and would like to take advantage of multithreading, the natural question is what parts of the program should/ should not be threaded. Here are a few rules of thumb (if you say “yes” to these, have fun!):
Are there groups of lengthy operations that don’t necessarily depend on other processing (like painting a window, printing a document, responding to a mouse-click, calculating a spreadsheet column, signal handling, etc.)?
Will there be few locks on data (the amount of shared data is identifiable and “small”)?
Are you prepared to worry about locking (mutually excluding data regions from other threads), deadlocks (a condition where two COEs have locked data that other is trying to get) and race conditions (a nasty, intractable problem where data is not locked properly and gets corrupted through threaded reads & writes)?
Could the task be broken into various “responsibilities”? E.g. Could one thread handle the signals, another handle GUI stuff, etc.?
Conclusions:- Whether you have to use threading or forking, totally depends on the requirement of your application.
- Threads more powerful than events, but power is not something which is always needed.
- Threads are much harder to program than forking, so only for experts.
- Use threads mostly for performance-critical applications.

Orphan Process

What is Orphan Process?It’s a pretty much common question asked in most of the interviews related to Linux, and most of the time people got it confused with Zombie Process. But these two are totally different from each other. An Orphan Process is nearly the same thing which we see in real world. Orphan means someone whose parents are dead. The same way Orphan process is a process, whose parents are dead, that means parents are either terminated, killed or exited but the child process is still alive.

In Linux/Unix like operating systems, as soon as parents of any process are dead, re-parenting occurs, automatically. Re-parenting means processes whose parents are dead, means Orphaned processes, are immediately adopted by special process “init”. Thing to notice here is that even after re-parenting, the process still remains Orphan as the parent which created the process is dead,
Reasons for Orphan Processes:
A process can be orphaned either intentionally or unintentionally. Sometime a parent process exits/terminates or crashes leaving the child process still running, and then they become orphan processes.
Also, a process can be intentionally orphaned just to keep it running. For example when you need to run a job in the background which don’t need any manual intervention and going to take long time, then you detach it from user session and leave it there. Same way, when you need to run a process in the background for infinite time, you need to do the same thing. Processes running in the background like this are known as daemon process.

At the same time, when a client connects to a remote server and initiated a process, and due to some reason the client crashes unexpectedly, the process on the server becomes Orphan.

Finding a Orphan Process:
It’s very easy to spot a Orphan process. Orphan process is a user process, which is having init (process id – 1) as parent. You can use this command in linux to find the Orphan processes.

# ps -elf | head -1; ps -elf | awk '{if ($5 == 1 && $3 != "root") {print $0}}' | headThis will show you all the
orphan processes running in your system. The output from this command confirms that they are Orphan processes but doesn’t mean that they are all useless, so confirm from some other source also before killing them.

Killing a Orphan Process:
As orphaned processes waste server resources, so it’s not advised to have lots of orphan processes running into the system. To kill a orphan process is same as killing a normal process.
# kill -15 <PID>If that don’t work then simply use
# kill -9 <PID>

FAQs:Q. Is Orphan process different from an Zombie process ?
A. Yes, Orphan process are totally different from Zombie processes. Zombie processes are the ones which are not alive but still have entry in parent table. For more details, please refer to — Zombie Processes.

Q. Are Orphan processes harmful for system ?
A. Yes. Orphan processes take resources while they are in the system, and can potentially leave a server starved for resources. Having too many Orphan processes will overload the init process and can hang-up a Linux system. We can say that a normal user who has access to your Linux server is capable to easily kill your Linux server in a  minute.

Zombie Process

What is a Zombie Process ?
It’s a pretty much common question asked in most of the interviews related to Linux, and most of the time people got it confused with Orphan Process. But these two are totally different from each other. A Zombie Process is nearly the same thing which we see in lot of horror movies. Like the dead people which don’t have any life force left, Zombie processes are the dead processes sitting in the process table and doing nothing.

To explain this in much better way, “Zombie process or defunct process is a process that have completed the execution, have released all the resources (CPU, memory) but still had an entry in the process table.”
Reasons of Zombie Process:
Most of the time, the reason for existence of Zombie process is bad coding. Normally, when a child (subprocess) finishes it’s task and exits, then it’s parent is suppose to use the “wait” system call and get the status of the process. So, until the parent process don’t check for the child’s exit status, the process is a
Zombie process, but it usually is very small duration. But if due to any reason (bad programming or a bug), the parent process didn’t check the status of the child and don’t call “wait”, the child process stays in the state of Zombie waiting for parent to check it’s status.

Finding Zombie processes:
To check whether you have any Zombie processes in your system, simply run linux command line utility “top”. It shows the number of zombie processes at the upper-right side of its output.
At the same time, you can use one more command to check that

# ps aux

All the processes which are having “z” in their Stat column are Zombie processes.

Killing a Zombie Process:
Well, before taking any decision of killing the Zombie process, you should wait, as it is possible that the parent process is intentionally leaving the process in a zombie state to ensure that future children that it may create will not receive the same pid. Or perhaps the parent is occupied, and will reap the child process momentarily.

If that didn’t happen then you can send a SIGCHLD signal to the parent process of zombie which will instruct parents to reap their zombie children.
# kill -s SIGCHLD <PPID>Even if this don’t work, then the last option you will have is to kill the parent process. You can easily find out the parent’s process ID with this command:
# ps aux -eo ppid | grep <Zombie Process ID>
# kill -9 <PPID>So when a Zombie process loses it’s parent process, it becomes orphan and adopted by “init”. Init periodically executes the wait system call to reap any zombies with init as parent.

FAQs:
Q. Why I can’t kill a Zombie process with “kill” command ?
A. Zombie process is already dead, so killing them with “kill -9″ won’t help at all.

Q. Is it bad to have Zombie processes on your system ?
A. Well, as Zombie processes are not taking any resources of your system, leaving a small entry in process table, it’s not at all harmful to have Zombie processes in your system, but it may hurt you sometime under heavy load. So, it’s always better not to have them.

Q. I am seeing a lots of Zombie processes around in my system, what could be the reason ?
A. If this is the case then you are using some code/software in your system which is having a lot of bugs or not properly written. Look for something like that and fix it.

Q. Is Zombie process different from an Orphan process ?
A. Yes, Zombie is something which is already dead, but Orphan processes are those whose parents are dead.