5.2.2 POSIX Thread Creation and Destruction

Figure: Threads Created Via pthread_create() Share Memory
\begin{figure}{ \scriptsize
\begin{verbatim}1 int x = 0;
2
3 void *mythrea...
...ent process sees x=%d\n'', x);
24 return 0;
25 }\end{verbatim}
}\end{figure}

To create a thread within an existing process, invoke the pthread_create() primitive, for example, as shown on line 15 of Figure [*] (pcreate.c). The first argument is a pointer to a pthread_t in which to store the ID of the thread to be created, the second NULL argument is a pointer to an optional pthread_attr_t, the third argument is the function (in this case, mythread() that is to be invoked by the new thread, and the last NULL argument is the argument that will be passed to mythread.

In this example, mythread() simply returns, but it could instead call pthread_exit().

Quick Quiz 5.6: If the mythread() function in Figure [*] can simply return, why bother with pthread_exit()? End Quick Quiz

The pthread_join() primitive, shown on line 19, is analogous to the fork-join wait() primitive. It blocks until the thread specified by the tid variable completes execution, either by invoking pthread_exit() or by returning from the thread's top-level function. The thread's exit value will be stored through the pointer passed as the second argument to pthread_join(). The thread's exit value is either the value passed to pthread_exit() or the value returned by the thread's top-level function, depending on how the thread in question exits.

The program shown in Figure [*] produces output as follows, demonstrating that memory is in fact shared between the two threads:



Child process set x=1
Parent process sees x=1


Note that this program carefully makes sure that only one of the threads stores a value to variable x at a time. Any situation in which one thread might be storing a value to a given variable while some other thread either loads from or stores to that same variable is termed a ``data race''. Because the C language makes no guarantee that the results of a data race will be in any way reasonable, we need some way of safely accessing and modifying data concurrently, such as the locking primitives discussed in the following section.

Quick Quiz 5.7: If the C language makes no guarantees in presence of a data race, then why does the Linux kernel have so many data races? Are you trying to tell me that the Linux kernel is completely broken??? End Quick Quiz

Paul E. McKenney 2011-12-16