Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

Share this Page URL

Chapter 18. Multiprocessing > fork() Gotchas - Pg. 502

Chapter 18 Multiprocessing FILE *blarg; char buffer[BUFSIZE]; blarg = fdopen (pipeline2[0], "r"); while (fgets(buffer, BUFSIZE, blarg)) { printf ("%s", buffer); } // and wait int childStatus; waitpid (grep_pid, &childStatus, 0); waitpid (tr_pid, &childStatus, 0); // whew! All done. status = EXIT_SUCCESS; bailout: return (status); } // main A sample run: $ ./pipeline AIRMAIL AUMAIL BEMAIL BLACKMAIL BLACKMAILER CAMAIL ... UNMAIL UNMAILABLE UNMAILABLENESS UNMAILED fork() Gotchas While Unix file descriptors are inherited across fork() , most Mach ports are not. Cocoa relies on Mach ports for much of its private interprocess communication, including communication with the window server. Expect problems if you try to use Cocoa after a fork() . When you are using threads (which Cocoa and Core Foundation programs use implicitly), only the thread that calls fork() is running in the child. Unfortunately, all of the other thread stuff (mutexes and other data structures) still exists, and data structures that are protected by mutexes are potentially still in an indeterminate state, which can lead to total mayhem. If you are using threads (or if a framework or library is using them on your behalf), the only safe functions to call after a fork() are the exec() functions and any of the async-signal-safe functions (the ones you can call in a signal handler). Under Mac OS X 10.6 and later, if you are using run loops, they are spinning up the Grand Central Dispatch workqueue threads on your behalf. The Foundation URL loading system uses threads, as do certain services in Core Foundation. Many other Apple frameworks use threads under the hood, as well. 502