life of a NPTL pthread

这是2013年写的一篇旧文,放在gegahost.net上面 http://raison.gegahost.net/?p=91

March 7, 2013

life of a NPTL pthread

Filed under: concurrency,linux,posix — Tags: NPTL, pthread — Raison @ 12:52 pm

(Original Work by Peixu Zhu)

NPTL pthread is the default pthread implementation under current Linux distributions. In concurrent/parallel programming, multiple threading is the basic technology, and knowledge of the NPTL thread’s life will make us clear on using pthread.

1. The nature of the NPTL pthread.

Naturally a NPTL pthread is a light weight pseudo process in Linux. Thus, the maximum of allowed pthread number is limited by the limitation of allowed processes to create in the system.  For a specific user, the number of processes to create is also limited. In system scope, we may get/set the maximum number of process at `/proc/sys/kernel/pid_max`, or by administration command `sysctl`, and get/set maximum number of threads at `/proc/sys/kernel/threads-max`.  For a specific user, we may get/set the maximum number of processes to running with by the command `ulimit   -u`.

Since they’re processes in nature, thus, they are scheduled by the kernel all.

Keep in mind that each thread exhaust a Process ID.

2. The creation of NPTL pthread

A NPTL thread is created by the system routine `__clone`, which allow child process to share parts of its  execution context with the calling process, including memory space, file descriptors, signal handler table, etc. .

The NPTL pthread library offers library function `pthread_create` to create a thread. As calling `pthread_create`, user provide it with necessary arguments like the attribute, the executor function, the argument for executor function. In `pthread_create`,  below preparation works are performed in sequence:

  • thread attributes are initialized,  with the argument attribute, and then a stack and thread context are allocated,   the thread context  including TCB, internal locks  etc., are initialized. In fact, the new thread id is the address of allocated stack. Thus, the count of allowed threads in a process is also limited by the memory for the process.
  • calling process/thread thread attribute flags and scheduling parameters are copied to the new thread, the join ID which required by `pthread_join` is initialized.
  • new thread scheduling policy is determined by the calling process scheduling parameters and argument attribute.
  • calling internal routine `create_thread` to create the thread, with the thread context, new thread stack, and attributes as arguments.

In internal function `create_thread`,  system routine `__clone` is called, with demanded arguments to create a thread(in fact a child process). When calling `__clone`,  a fixed helper routine `start_thread` is feed instead of the thread executor function, when `__clone` successfully create the new thread (child process), the helper routine `start_thread` is executed, when `start_thread` finished, it returns the error code as the exiting code of the thread. The new thread executor function is executed in `start_thread`.

3. Cleanup of NPTL pthread

In helper routine `start_thread`, after the thread executor function is executed, the return value is stored in the thread context, then, the routine runs step by step as below:

  • run the destructor for the thread-local data.
  • if the thread is the last thread in process, terminate the process.
  • set the thread to be EXITING.
  • if the system support robust mutex, and if there’s robust mutex hooked on the thread, make all of them dead, thus, any sequent access of them will be signalled with EOWNERDEAD.
  • recycle the stack of the thread, leaving TCB not freed.
  • if the thread is detached,  TCB is freed.
  • call system call to terminate the thread.

4. pthread_join and pthread_detach

`pthread_join` is supposed to join the target thread, provided that the target thread is joinable. If the target thread is not terminated yet, the calling thread will waiting for the target thread to be terminated, after the target thread is terminated, it will clean up the TCB of the target thread which is not recycled when the target thread finish running, and then return to the calling thread. If the target thread is already terminated, the calling thread returns from `pthread_join` soon.

`pthread_detach` is supposed to detach a joinable target thread. If the target thread is detached ready, error returned. The routine does not terminate the target thread, it just change `joinid` of the thread context.

A detached thread will recycle its TCB when it is terminated, and a joinable thread will remain its TCB when it is terminated, until a calling of `pthread_join` is called to recycle it. A thread is default to be joinable, unless it is explicitly set to be detached when it is created.

时间: 2024-10-15 02:15:41

life of a NPTL pthread的相关文章

pthread_create

//\glibc-2.24\sysdeps\nptl\pthread.h/* Create a new thread, starting with execution of START-ROUTINE getting passed ARG. Creation attributed come from ATTR. The new handle is stored in *NEWTHREAD. */ extern int pthread_create (pthread_t *__restrict _

NPTL vs PThread

NPTL vs PThread POSIX threads (pthread) is not an implementation, it is a API specification (a standard, on paper, in english) of several functions whose name starts with pthread_ and which are defined in <pthread.h> header. POSIX is also a set of s

pthread多线程编程的学习小结

pthread多线程编程的学习小结 程序员必上的开发者服务平台 —— DevStore pthread多线程编程整理 1 Introduction 不用介绍了吧… 2 Thread Concepts 1.     Thread由下面部分组成: a.     Thread ID b.     Stack c.     Policy d.     Signal mask e.     Errno f.      Thread-Specific Data 3 Thread Identification

posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序

posix 线程(一):线程模型.pthread 系列函数 和 简单多线程服务器端程序 一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型. (一).N:1用户线程模型 “线程实现”建立在“进程控制”机制之上,由用户空间的程序库来管理.OS内核完全不知道线程信息.这些线程称为用户空间线程.这些线程都工作在“进 程竞争范围”(process contention scope):各个线程在同一进程竞争“被调度的CPU时间”(但

Linux多线程编程和Linux 2.6下的NPTL

Linux多线程编程和Linux 2.6下的NPTL 在Linux 上,从内核角度而言,基本没有什么线程和进程的区别--大家都是进程.一个进程的多个线程只是多个特殊的进程他们虽然有各自的进程描述结构,却共享了同一 个代码上下文.在Linux上,这样的进程称为轻量级进程Light weight process.致此,就是关于线程的总体概念了,我们往往就在了解这个概念的情况下开始我们的多线程编程之旅.这对于多线程编程入门已经足够了,然而事 实上线程却要复杂的多. 首先多线程间的优先级调度,内存资源(

NPTL分析之线程的创建

NPTL(NativePosix Thread Library) NPTL包括pthread线程库以及配套的同步方法,我们这里暂时只讲pthread线程库的实现. 1. NPTL的起源 在NPTL之前,linux的线程库是LinuxThreads,该库部分实现了Posixthreads的规范.其主要特点是线程的调度在用户态完成,且由一个管理线程来调度.相应的,其缺点也来自于这种架构,导致管理线程带来了很大的任务切换的开销.另外一个问题是LinuxThreads对信号的处理不满足Posixthre

从pthread中获得tid及pthread_mutex_unlock本身用户态互斥

一.pthread结构中获取tid 这个问题是由于很多时候我们都是通过gettid来获得一个线程的tid,其实这个是一个非常简单的系统调用,但是即使它非常简单,我们还是要执行进行系统调用而引入的寄存器保存/恢复等操作.但是,在C库的pthread库的实现过程中,我们可以看到,用户态是肯定保存了一个线程的tid的,如果我们能够通过用户态这个一定会存在的pthread结构来获得这个tid,就可以避免大量的系统调用,从而为系统的效率提供方便. 1.C库实现方法 __pthread_create_2_0

Thread ID vs Pthread Handle(pthread_t)

在很多线程实现的案例中,pthread_t作为抽象类型,被指定为长度为4的整行作为线程ID. 在一些iSeries服务器的线程实现上,线程ID是一个64位的整型数值和pthread_t是一个抽象 的结构体包含数值和一些其他的参数.抽象化允许进程容纳上千个线程. 如果不允许移植,不允许进程访问pthread_t的内部数据和尺寸,例如对比线程ID,对于可移植的对比, 使用pthread_equal函数.文档通常描述pthread_t作为线程句柄,避免因为使用一个整型表示线程ID 而混淆概念, Thr

iOS开发 - 多线程实现方案之Pthread篇

pthread基础 pthread是POSIX thread的简写,一套通用的多线程API,适用于Unix.Linux.Windows等系统,跨平台.可移植,使用难度大,C语言框架,线程生命周期由程序员管理,百度百科上有详细的介绍,去查看,由于iOS开发几乎用不到,以下就简单运用pthread开启一个子线程,用来处理耗时操作 pthread创建子线程步骤 1.导入头文件 #import <pthread.h> 2.pthread创建子线程 - (void)viewDidLoad { [supe