一文打尽pthread库
pthread(POSIX Threads)是遵循 POSIX 标准的线程库,广泛用于 Unix/Linux 系统中实现多线程编程。它提供了一组 C 语言 API,用于创建、管理、同步线程。以下是对 pthread 库及相关函数的系统性总结:
一、基本概念
线程(Thread):轻量级进程,共享进程地址空间,独立执行流。
主线程:程序启动时默认创建的线程。
并发 vs 并行:并发是逻辑上同时执行,并行是物理上同时执行(多核)。
线程安全:函数/数据结构在多线程环境下能正确工作。
二、核心数据类型
1 | #include <pthread.h> |
三、线程管理函数
1. 创建线程
1 | int pthread_create(pthread_t *thread, |
thread:输出参数,新线程 ID。
attr:线程属性,NULL 表示默认。
start_routine:线程入口函数。
arg:传递给入口函数的参数。
返回值:0 成功,非 0 错误码(非 errno)。
⚠️ 注意:必须链接 -lpthread(或 -pthread)
2. 等待线程结束(阻塞)
1 | int pthread_join(pthread_t thread, void **retval); |
阻塞调用线程,直到目标线程结束。
可获取线程返回值(通过 retval)。
适用于需要同步或回收资源的场景。
3. 分离线程(非阻塞回收)
1 | int pthread_detach(pthread_t thread); |
线程结束后自动释放资源,无需 pthread_join。
不能对已分离线程调用 pthread_join。
4. 获取当前线程 ID
1 | pthread_t pthread_self(void); |
5. 比较线程 ID
1 | int pthread_equal(pthread_t t1, pthread_t t2); |
- 返回非 0 表示相等。
6. 退出线程
1 | void pthread_exit(void *retval); |
主动终止当前线程,可传递返回值。
主线程调用 pthread_exit 不会终止整个进程(除非是最后一个线程)。
四、线程属性设置(可选)
1 | int pthread_attr_init(pthread_attr_t *attr); |
五、线程同步机制
1. 互斥锁(Mutex)
用于保护临界区,防止多个线程同时访问共享资源。
1 | pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 静态初始化 |
🔒 使用模式:
1 | pthread_mutex_lock(&mutex); |
2. 条件变量(Condition Variable)
用于线程间通信,常与互斥锁配合使用,实现“等待某个条件成立”。
1 | pthread_cond_t cond = PTHREAD_COND_INITIALIZER; |
🔄 典型使用模式:
1 | pthread_mutex_lock(&mutex); |
3. 读写锁(Read-Write Lock)
允许多个读者同时访问,写者独占访问。
1 | pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; |
适合“读多写少”场景。
4. 自旋锁(Spinlock)【可选】
忙等待锁,适用于锁持有时间极短的场景。
1 | pthread_spinlock_t spinlock; |
六、线程局部存储(TLS)
每个线程拥有独立的变量副本。
1 | pthread_key_t key; |
类似于 C11 的 _Thread_local 或 GCC 的 __thread。
七、取消机制(Cancellation)
允许一个线程请求终止另一个线程。
1 | int pthread_cancel(pthread_t thread); // 发送取消请求 |
⚠️ 取消点(Cancellation Points):如 sleep, read, write, pthread_cond_wait 等阻塞函数。
八、一次初始化(One-time Initialization)
确保某段初始化代码只执行一次。
1 | pthread_once_t once_control = PTHREAD_ONCE_INIT; |
常用于初始化全局资源(如互斥锁、TLS key)。
九、常见错误处理
pthread 函数不设置 errno,而是直接返回错误码:
1 | int ret = pthread_create(...); |
或使用 perror 需要先设置 errno:
1 | errno = ret; |
十、编译与链接
1 | gcc -o program program.c -lpthread |
十一、最佳实践与注意事项
避免死锁:加锁顺序一致,避免嵌套锁。
资源回收:join 或 detach 所有线程,避免资源泄漏。
线程安全函数:避免使用非线程安全函数(如 strtok, rand → 改用 strtok_r, rand_r)。
信号处理:线程中慎用信号,推荐使用 sigwait 或指定信号处理线程。
性能考虑:锁粒度不宜过大,避免频繁加锁。
调试工具:使用 valgrind –tool=helgrind 或 ThreadSanitizer 检测竞争条件。
十二、简单示例
1 | #include <pthread.h> |
总结
功能主要函数创建线程pthread_create等待线程pthread_join分离线程pthread_detach互斥锁pthread_mutex_*条件变量pthread_cond_*读写锁pthread_rwlock_*线程局部存储pthread_key_*一次初始化pthread_once线程取消pthread_cancel, pthread_testcancel
掌握 pthread 库是进行 Linux/Unix 系统级并发编程的基础。合理使用同步机制、避免竞态条件和死锁,是编写健壮多线程程序的关键。
✅ 推荐学习顺序:线程创建 → 互斥锁 → 条件变量 → 读写锁 → 高级特性(TLS、取消、一次初始化)📚 参考资料:《UNIX环境高级编程》、《POSIX标准文档》、Linux man pages (man pthread_create)
以下是《UNIX环境高级编程》和《POSIX标准文档》的官方或权威获取链接:
📘 1.《UNIX环境高级编程》(Advanced Programming in the UNIX Environment, 简称 APUE)
作者:W. Richard Stevens & Stephen A. Rago
当前最新版:第3版(2013),涵盖 POSIX.1-2008 和 UNIX System V / BSD 扩展
官方出版商页面:👉 https://www.apuebook.com/
该网站由作者 Stephen Rago 维护,提供:
源代码下载(所有示例代码)
勘误表(errata)
各章摘要和更新说明
非常适合配合学习使用
购买纸质/电子书:
Amazon:https://www.amazon.com/Advanced-Programming-UNIX-Environment-3rd/dp/0321637739
中国读者可在京东、当当购买中文翻译版(译者:戚正伟 等)
⚠️ 本书无“开源免费电子版”,请支持正版。
📜 2.《POSIX 标准文档》(IEEE Std 1003.1)
POSIX 是由 IEEE 和 The Open Group 共同维护的标准,官方文档需通过其网站获取。
✅ 官方免费在线查阅版(HTML):
👉 The Open Group Base Specifications, Issue 7 (2018) — POSIX.1-2017🔗 https://pubs.opengroup.org/onlinepubs/9699919799/
这是当前最权威、最新且免费公开访问的 POSIX 标准文档(含 Shell、Utilities、System Interfaces、Headers 等)。
包含所有 pthread 函数规范(如 pthread_create, pthread_mutex_lock 等)
可直接搜索函数名,查看标准定义、参数、返回值、错误码、可移植性说明
支持书签、交叉引用,适合开发者查阅
📄 PDF 下载版(需注册,部分免费):
👉 https://publications.opengroup.org/standards/unix
注册后可免费下载 PDF(部分文档需付费)
搜索 “IEEE Std 1003.1™-2017” 或 “The Open Group Base Specifications Issue 7”
🆚 IEEE 官方标准购买页面(付费):
👉 https://standards.ieee.org/standard/1003_1-2017.html
IEEE 出版的正式标准文档(PDF)
价格较高(约 $200+),适合企业或标准研究者
内容与 The Open Group 版本基本一致
✅ 对于绝大多数开发者,The Open Group 免费在线版已完全足够。
📌 补充:Linux man pages(在线)
虽然不是“标准文档”,但 Linux man pages 是最实用的函数参考:
🔗 https://man7.org/linux/man-pages/
搜索 pthread_create → https://man7.org/linux/man-pages/man3/pthread_create.3.html
包含函数原型、描述、示例、错误码、遵循标准(如 POSIX.1-2001)
由 Michael Kerrisk(《The Linux Programming Interface》作者)维护,权威可靠
✅ 总结推荐
资源名称类型推荐链接备注《APUE》官网图书配套https://www.apuebook.com/源码+勘误,必备POSIX 标准在线文档官方标准https://pubs.opengroup.org/onlinepubs/9699919799/免费、权威、最新Linux man-pages函数手册https://man7.org/linux/man-pages/实用开发参考IEEE POSIX 标准购买付费标准https://standards.ieee.org/standard/1003_1-2017.html企业/研究用
📘 建议学习路径:
学 pthread → 查 man7.org 快速上手
深入理解标准行为 → 查 Open Group POSIX 文档
系统学习 UNIX 编程 → 读 APUE 第3版