How Are Posix Threads Implemented on Linux

How are POSIX Threads implemented on Linux?

Before Linux 2.6 they were essentially userspace threads, separate processes which were glued together, because the kernel had no real thread support. Edit: There was some limited support for kernel level threads (a clone() function) before 2.6, but it wasn't used with posix threads, only with an alternative thread library called linuxthreads.
Since the arrival of NPTL (Native Posix Thread Library) the are kernel threads.

How does pthread implemented in linux kernel 3.2?

On Linux pthread uses the clone syscall with a special flag CLONE_THREAD.

See the documentation of clone syscall.

CLONE_THREAD (since Linux 2.4.0-test8)

If CLONE_THREAD is set, the child is placed in the same thread group as the calling process. To make the remainder of the discussion of CLONE_THREAD more readable, the term "thread" is used to refer to the processes within a thread group.

Thread groups were a feature added in Linux 2.4 to support the POSIX threads notion of a set of threads that share a single PID. Internally, this shared PID is the so-called thread group identifier (TGID) for the thread group. Since Linux 2.4, calls to getpid(2) return the TGID of the caller.

And in fact, Linux do change its thread implementation, since POSIX.1 requires threads share a same process ID.

   In the obsolete LinuxThreads implementation, each of the threads in a process
has a different process ID. This is in violation of the POSIX threads
specification, and is the source of many other nonconformances to the
standard; see pthreads(7).

How are pthreads implemented in Linux kernel(2.6) using NPTL?

Look at this paper of design and implementation of NPTL by Ulrich Drepper and Ingo Molnar
http://www.akkadia.org/drepper/nptl-design.pdf

I believe a lot had been changed since 2005 and it's not should be used as a reference to point out limitations and shortcomings (that said in header), though it's a great doc about overall design.

POSIX threads vs parallelism

Posix threads are kernel threads with glibc/musl (+possibly other pthread implementations) on Linux.

GNU/Linux thread implementation

Just reading the relevant lines from book and the example shared by you, it is clear that it is related to specific implementation of POSIX threads on GNU/Linux

In GNU/Linux, threads are implemented as processes. 

Hence, Whenever you call pthread_create to create a
new thread, Linux creates a new process that runs that thread.

So in example code, when you do pthread_create(&thread, NULL, thread_func, NULL); the implementation creates a new process to run this newly created thread. This process will have a different PID (which is what getpid()call displays).

So, now you already have 2 process, one main process which is launched when you run the program and this new process created by system to support thread execution.

And the same implementation is also creating another process (which is internal to its implementation), which is termed as manager thread. And this is created when you invoke pthread_create

Is there a difference in how threads work in Linux vs Unix vs Solaris

The original Unix does not use threads for multiprogramming. An article from 1987 comparing the Mach and Unix kernel states that "neither Unix System V nor 4.3 BSD provide a way to manage more than one thread of control within an address space".

Modern Unix clones adhere to the POSIX Threads specification. The POSIX Threads standard only appeared in 1995. The underlying implementation in Linux is based on the clone() and futex() system calls, which are implemented by the kernel. The clone() system call creates a new lightweight process that can share a memory space with its child. So, for example, the pthread_create() library call internally calls the clone() system call. The futex() system call implements a synchronization primitive that can be used for creating larger synchronization operations, like mutexes, semaphores, etc. So, for example, pthread_mutex_lock() will call futex() internally.

Using POSIX terminology, Linux implementation model is a "kernel-thread model", also known as 1:1 model, where 1 kernel lightweight process is used for 1 user visible thread.

Linux also had different threading implementations over time. More description about threading support in Linux in pthreads(7), clone(2) and futex(2) manual pages.

Other implementations may be completely different and still implement the POSIX threads API. FreeBSD used a M:N implementation, or "hybrid model", where an user visible thread could be managed either by the kernel, or by a user space library. See the kse(2) manual page for a complete description. I have once traced the current 1:1 FreeBSD threading implementation to an article in kerneltrap:

http://web.archive.org/web/20110512021159/http://kerneltrap.org/node/624

OpenSolaris doesn't seem to describe its own threading implementation on man pages. I could find instead a document comparing the OpenSolaris kernel with Linux 2.6 and Windows Vista. There, a main difference between the Linux and OpenSolaris implementation is that in Linux, each process is a lightweight process, unifying threads and processes, while in OpenSolaris one process contains multiple lightweight processes, in practice separating in the kernel the process from the kernel thread.

References:

http://en.wikipedia.org/wiki/Thread_(computing)

http://en.wikipedia.org/wiki/POSIX_Threads

http://repository.cmu.edu/cgi/viewcontent.cgi?article=2728&context=compsci

http://man7.org/linux/man-pages/man7/pthreads.7.html

http://man7.org/linux/man-pages/man2/clone.2.html

http://man7.org/linux/man-pages/man2/futex.2.html

http://pubs.opengroup.org/onlinepubs/7908799/xsh/threads.html

http://www.freebsd.org/cgi/man.cgi?query=kse&apropos=0&sektion=0&manpath=FreeBSD+7.2-RELEASE&format=html

http://web.archive.org/web/20110512021159/http://kerneltrap.org/node/624

http://www.unix.com/man-page/opensolaris/5/threads/

http://www.infoq.com/articles/kernel-comparison-unix-zhu



Related Topics



Leave a reply



Submit