Forking in a multi-threaded environment is a difficult task. There may be difficulties
Case 1: If all the threads are copied and the fork() call is blocking.
Suppose the Thread T1 is executing in Parent and has got a lock on some critical section. Meanwhile fork() is called. All the thread in the parent become blocked. When the copy of the thread T1 (c1) tries to execute it gets blocked as the lock is still held by T1. Therefore both the process get blocked.
Case 2: Single Thread Copy
Assume that the thread executing the fork() statement is only copied to the child process. There may be a case where the child process may grab on to a resource already held by parent.
Example: Suppose printf() is executing in thread T1 and is forked to T2(child).The parent does a blocking call. Now T2 has only one thread that does printf. Now the thread T2 tries to printf but the lock is already held by the parent process. Therefore a dead lock occurs.
In reality what happens is that after fork() the child calls the exec() . This flushes all the executable of parent in child and loads new copy of executable in child.