Subj : Re: pthreads and fork To : comp.programming.threads From : Marcin 'Qrczak' Kowalczyk Date : Mon Feb 21 2005 10:49 am David Hopwood writes: > Why include fork at all in your language? Because I want to give access to a reasonable subset of Unix API in an optional library, to reduce the need to write programs in C. > - cancelling threads after fork is *not* a good default. This makes > it essentially impossible to write fork-safe libraries that output > to external resources: on a fork you will end up with two processes > outputting to the resource, which will invariably trash it. It's not impossible because you can register handlers which are run around a fork, similarly to pthread_atfork. Such a handler can take the mutex used for output. (There is also an issue of duplicating output because of data left in buffers, exactly as with C fork. Such handlers can flush files if desired. By default StdOut and StdErr are flushed.) If output doesn't use a mutex, e.g. because only one thread performs it, then such thread will be canceled immediately at fork and output will not be duplicated. By default it has asynchronous signals unblocked. Yes, it's not safe automatically, you have to establish these handlers. That's why I'm still investigating a different semantics where the thread doing the fork would suspend all threads in their safes points first, and after fork cancel them from that points. I think waiting for them to have signals unblocked has the right semantics most of the time. There are two problems with this approach. It's very tricky to implement compared to just cancellation in the child process after forking (e.g. newly created threads must be chased), and I'm not at all convinced that a well-behaved thread should never run with signals blocked for long periods of time. Maybe there are should be separate fork variants with different semantics. I don't like that, but it's not obvious what to choose. > - fork+exec can and should be replaced by popen in almost all cases. We can have both. My variant od popen is currently implemented using calls to other functions in my language rather than an atomic C snippet (the calls redirect stdio, close unneeded files, set the current directory and change environment variables). This suggests that a different variant of fork might be used for cases where it's soon followed by exec. The mentioned operations don't use mutexes so they would work even if other threads were evaporated. Well, there is a problem that it also runs registered exec handlers (which are used for flushing stdout/stderr) and they might use mutexes etc. In this case flushing stdout/stderr is not necessary, because it already happened before the fork. These handlers make sense in general however because I also give access to exec without a fork. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/ .