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
What's The Purpose of Mmap Memory Protection Prot_None
Linux Service Can't Load Library Path in The /Etc/Ld.So.Conf.D
Linux: How to Debug a Sigsegv? How to Trace The Error Source
Why Processes Are Deprived of CPU for Too Long While Busy Looping in Linux Kernel
Running Docker on Google Colab
Checking If a Binary Compiled with "-Static"
How to Find Files Except Given Name
Difference Between Arm-None-Eabi and Arm-Linux-Gnueabi
How to Use Systemd to Restart a Service When Down
Where to Put Svn Repository Directory in Linux
What Is The Fastest Way to Display an Image in Qt on X11 Without Opengl
How to Curl Using Ipv6 Address
How to Get Percentage of Processor Use with Bash