OS 中的 POSIX 线程2025年4月29日 | 9 分钟阅读 POSIX 线程通常称为 PThreads。它是一种独立于语言和并行执行模型的执行模型。它允许程序控制多个重叠的时间段内的不同工作流。每个工作流称为一个 线程。通过调用 POSIX 线程 API 来创建和控制这些流。POSIX 线程是 POSIX.1c 标准、线程扩展(IEEE Std 1003.1c-1995)定义的 API。 该 API 的实现可在许多类 Unix POSIX 兼容的操作系统上使用,例如 FreeBSD、NetBSD、OpenBSD、Linux、macOS、Android、Solaris、Redox 和 AUTOSAR Adaptive,通常以库 libPThread 的形式提供。DR-DOS 和 Microsoft Windows 实现也存在于 SFU/SUA 子系统中,该子系统提供了许多 POSIX API 的原生实现,以及第三方软件包(如 PThreads-w32),该软件包在现有 Windows API 之上实现了 PThreads。 PThreads 是一个高度具体的**多线程**系统,是 UNIX 系统的默认标准。PThreads 是 POSIX 线程的缩写,POSIX 是可移植操作系统接口的缩写,它是一种操作系统必须实现的接口类型。POSIX 中的 PThreads 概述了操作系统必须提供的线程 API。 PThreads 在多处理器或多核系统上效果良好,在这些系统中,进程流可以被调度到另一个处理器上执行,通过并行或分布式处理提高速度,因为系统不必为进程创建新的系统、虚拟内存空间和环境,线程比分叉或创建新进程的开销小得多。 PThread 头文件 要使用 PThread 接口,我们必须在 CPP 脚本的开头包含 PThread.h 头文件。 为什么要使用 PThreads?以下是关于在操作系统中使用 PThreads 的原因,例如:
示例PThreads 定义了一组 C 编程语言类型、函数和常量。它通过 PThread.h 头文件和线程库实现。 大约有 100 个线程过程,都以 PThread_ 作为前缀,它们可以分为以下四组:
POSIX 信号量 API 可与 POSIX 线程配合使用,但不是线程标准的一部分,它已在 POSIX.1b 实时扩展(IEEE Std 1003.1b-1993)标准中定义。因此,信号量过程的前缀是 sem_ 而不是 PThread_。下面是一个演示在 C 中使用 PThreads 的示例。 上面的程序创建了五个线程,每个线程执行 perform_work 函数,该函数将该线程的唯一编号打印到标准输出。如果程序员希望线程相互通信,则需要定义一个在任何函数作用域之外的变量,将其声明为全局变量。可以使用 gcc 编译器通过以下命令编译此程序: 输出 这是运行该程序的一种可能输出。 IN MAIN: Creating thread 0. IN MAIN: Creating thread 1. IN MAIN: Creating thread 2. IN MAIN: Creating thread 3. THREAD 0: Started. IN MAIN: Creating thread 4. THREAD 3: Started. THREAD 2: Started. THREAD 0: Will be sleeping for 3 seconds. THREAD 1: Started. THREAD 1: Will be sleeping for 5 seconds. THREAD 2: Will be sleeping for 4 seconds. THREAD 4: Started. THREAD 4: Will be sleeping for 1 second. IN MAIN: All threads are created. THREAD 3: Will be sleeping for 4 seconds. THREAD 4: Ended. THREAD 0: Ended. IN MAIN: Thread 0 has ended. THREAD 2: Ended. THREAD 3: Ended. THREAD 1: Ended. IN MAIN: Thread 1 has ended. IN MAIN: Thread 2 has ended. IN MAIN: Thread 3 has ended. IN MAIN: Thread 4 has ended. MAIN program has ended. Windows 版 POSIX 线程Windows 不原生支持 PThreads 标准。因此 PThreads4w 项目旨在提供一个可移植的开源包装器实现。此外,它还可以用于将 UNIX 软件(使用 PThreads)以很少或无需修改的方式移植到 Windows 平台。 PThreads4w 版本 3.0.0 或更高版本,在 Apache Public License v2.0 下发布,与 64 位或 32 位 Windows 系统兼容。版本 2.11.0,在 LGPLv3 许可证下发布,也与 64 位或 32 位兼容。 Mingw-w64 项目还包含 PThreads 和 winPThreads 的包装器实现,后者比 PThreads4w 项目使用更多的原生系统调用。 Windows Services for UNIX/Subsystem for UNIX-based Applications 包中提供的 Interix 环境子系统提供了 PThreads API 的原生端口,即不映射到 Win32/Win64 API,而是直接构建在操作系统系统调用接口之上。 PThreads 中的扩展工具以下是 PThreads 中可用的扩展工具列表,例如:/p>
基本 PThreads 库调用以下是对 PThreads 库调用的简要介绍,例如:
PThread_create 子程序创建一个新线程,并使用 attr 参数指定的属性对象初始化其属性。新线程继承其创建线程的信号掩码,但创建线程的任何挂起信号都将为新线程清除。 新线程通过 arg 参数使其可运行,并将执行 start_routine 例程。arg 参数是一个 void 指针,用于引用任何数据。 PThread_create 子程序通过线程参数返回新的线程标识符。调用者可以使用此线程标识符对线程执行各种操作。应检查此标识符以确保线程已成功创建。
PThread_exit 子程序安全地终止调用线程,并为可能加入调用线程的任何线程存储终止状态。 与 exit 子程序不同,PThread_exit 子程序不会关闭文件。因此,任何仅由调用线程打开和使用的文件都必须在调用此子程序之前关闭。从线程的初始例程返回将隐式调用 PThread_exit 子程序,并使用返回值作为参数。
PThread_self 子程序返回调用线程的标识符。 int PThread_join:PThread_join 子程序会阻塞调用线程,直到调用中指定的线程终止。目标线程的终止状态在 status 参数中返回。 如果目标线程已经终止但尚未分离,则子程序会立即返回。即使目标线程尚未终止,也无法连接(join)一个已分离的线程。在所有连接的线程被唤醒后,目标线程会自动分离。 此子程序本身不会导致线程终止。它就像 PThread_cond_wait 子程序一样,用于等待一个特殊条件。
PThread_detach 子程序指示实现,当线程终止时,线程标识符位于 thread 位置的线程的存储可以被回收。此存储将在进程退出时被回收,无论线程是否已被分离,并且可能包括线程返回值占用的存储。 如果线程尚未终止,PThread_detach 不会导致其终止。对同一目标线程多次调用 PThread_detach 会导致错误。 如果目标线程已经终止但尚未分离,则子程序会立即返回。即使目标线程尚未终止,也无法连接(join)一个已分离的线程。在所有连接的线程被唤醒后,目标线程会自动分离。 此子程序本身不会导致线程终止。它就像 PThread_cond_wait 子程序一样,用于等待一个特殊条件。
PThread_mutex_init 子程序根据 mutex 属性对象 attr 初始化一个新的互斥锁并设置其属性。互斥锁最初是解锁的。 初始化互斥锁后,可以重复使用该互斥锁属性对象来初始化另一个互斥锁或将其删除。
PThread_mutex_destroy 子程序删除互斥锁。删除互斥锁后,mutex 参数无效,直到通过调用 PThread_mutex_init 子程序再次初始化它。
通过调用 PThread_mutex_lock 来锁定由 mutex 引用的互斥锁对象。如果互斥锁已被锁定,则调用线程将阻塞,直到互斥锁可用。此操作以由 mutex 引用的互斥锁对象处于锁定状态且调用线程持有该对象的方式返回。
PThread_mutex_trylock 函数与 PThread_mutex_lock 类似,但如果由 mutex 引用的互斥锁对象当前被锁定(由任何线程,包括当前线程),则调用将立即返回。
PThread_mutex_unlock 函数释放互斥锁对象。互斥锁的释放方式取决于互斥锁的类型属性。如果在调用 PThread_mutex_unlock 时有线程阻塞在互斥锁对象上,则互斥锁变得可用,并使用调度策略来确定哪个线程将获取该互斥锁。 下一主题回溯-操作系统 |
我们请求您订阅我们的新闻通讯以获取最新更新。