Page 1 of 1
locking vs. fork()
Posted: Sat Apr 25, 2009 9:52 am
by csko
Hi!
I'm just thinking what would be the proper way of cloning the locking
context of a process when fork() is called.
My idea is that all locks held by other threads (other threads = all
threads from current process - the thread that called fork) should be
released, otherwise if the new process tries to lock any of them would
cause a deadlock. The locks that are held by the thread that called
fork should be kept in the same state. The remaining, the locks that
are free (not held by any of the threads) should be copied simply
without any hacking.
What do you think about this?
Thanks,
csko
Re: locking vs. fork()
Posted: Sat Apr 25, 2009 1:46 pm
by 01000101
I'd suggest unlocking the core kernel thread (the one that forks()) and allowing the created threads the ability to lock instead. The core thread shouldn't really need a lock as I'd assume its main task is to spawn other threads, not much that it really needs to "lock" for. Also, when you spawn a new thread from an already locked one, interrupts should probably be disabled anyway so how would the child thread cause a deadlock? =)
Re: locking vs. fork()
Posted: Sat Apr 25, 2009 2:35 pm
by csko
There's one point that you missed
The fork() call will create a new process, not a new thread. The new process will
have only one thread with the same EIP value as the thread that called fork() previously.
So during fork, I have to clone the caller process' memory context, I/O context and locking context.
Let's see the following scenario, you may got what I meant with the deadlock:
Code: Select all
Process #1
Thread #2
l=create_lock()
lock(l)
Thread #1
fork()
Process #2
Thread #1
lock(l)
The lock() call in Process #2 will cause a deadlock because there's no other thread in process #2 that will unlock the 'l' lock.
Re: locking vs. fork()
Posted: Sat Apr 25, 2009 7:56 pm
by frank
From
http://www.opengroup.org/onlinepubs/000 ... /fork.html
File locks set by the parent process shall not be inherited by the child process.
The child process shall not inherit any address space memory locks established by the parent process via calls to mlockall() or mlock().
Any semaphores that are open in the parent process shall also be open in the child process.
A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called. [THR] [Option Start] Fork handlers may be established by means of the pthread_atfork() function in order to maintain application invariants across fork() calls. [Option End]
When the application calls fork() from a signal handler and any of the fork handlers registered by pthread_atfork() calls a function that is not asynch-signal-safe, the behavior is undefined.
It's the application's job to make sure it doesn't rely on threads to clear a semaphore or mutex held by a thread. It's the OS's responsibility to clear file and memory locks in the new process.
Re: locking vs. fork()
Posted: Fri May 01, 2009 2:43 pm
by Owen
Besides, it's probably better from a debugging perspective that an app deadlocks rather than behave strangely.