当前位置: 首页 > news >正文

整理pthread库函数(线程)

目录

  • 1. 线程创建
  • 2. 线程退出
  • 3. 线程等待
  • 4. 线程取消
  • 5. 线程清理处理程序
  • 6. 互斥锁(Mutex)
    • 6.1 初始化
    • 6.2 上锁与解锁
    • 6.3 尝试上锁
    • 6.4 性能测量(时间获取)
  • 7. 自旋锁(Spin Lock)
  • 8. 读写锁(Read-Write Lock)
  • 9. 条件变量(Condition Variable)

1. 线程创建

函数原型:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

参数说明:

  • thread:指向线程标识符(ID)的指针,用于获取新创建线程的 ID。
  • attr:线程属性指针,传入 NULL 表示使用系统默认属性。可配置属性包括:
    • 分离状态(Detach State):设为分离态后,线程终止时自动回收资源,无需主线程调用 pthread_join。
    • 栈空间大小(Stack Size):可手动调整线程栈内存,既能缩小栈空间以提升高并发下的内存利用率,又能增大栈空间防止溢出。
    • 调度策略与优先级(Scheduling Policy & Priority):允许配置 SCHED_FIFO 或 SCHED_RR 等实时调度算法并指定线程优先级,以满足高实时性或抢占式任务的需求。
  • start_routine:线程入口函数指针(回调函数),相当于子线程的 main 函数,由操作系统调用。
  • arg:传递给线程入口函数的参数,无参数时可传入 NULL。

2. 线程退出

线程退出的两种方式:

  1. 线程入口函数返回:在入口函数中执行return (void*)value;
  2. 显式调用退出函数:在任何位置调用void pthread_exit(void *retval);

3. 线程等待

函数原型:

int pthread_join(pthread_t thread, void **retval);

功能:等待指定线程结束,并获取其返回值。

参数说明:

  • thread:要等待的线程 ID。
  • retval:指向线程返回值的二级指针。若不需要获取返回值,可传入 NULL。

4. 线程取消

取消线程:

int pthread_cancel(pthread_t thread);

向指定线程发送取消请求。取消操作不会立即生效,线程会运行到最近的“取消点”时才退出。

设置取消点:

void pthread_testcancel(void);

手动设置一个取消点,允许线程在此处检查并响应取消请求。

5. 线程清理处理程序

压入清理函数:

void pthread_cleanup_push(void (*routine)(void *), void *arg);

弹出清理函数:

void pthread_cleanup_pop(int execute);

说明:

  • pthread_cleanup_push用于注册一个清理函数,当线程被取消或调用pthread_exit时,该函数会被自动调用。
  • pthread_cleanup_pop用于移除最近压入的清理函数。
    • execute参数为 0,则只弹栈不执行清理函数。
    • execute参数大于 0,则弹栈并执行清理函数。
  • 注意:pushpop必须成对出现,且通常紧跟在可能分配资源的操作(如malloc)之后。

特殊行为:调用pthread_exit(NULL)会弹出所有已注册的清理函数,并依次执行每个清理函数。

6. 互斥锁(Mutex)

6.1 初始化

动态初始化:

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
  • mutex:指向互斥锁变量的指针。
  • attr:互斥锁属性指针,通常传入 NULL 表示默认属性。

静态初始化:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

6.2 上锁与解锁

int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);

6.3 尝试上锁

int pthread_mutex_trylock(pthread_mutex_t *mutex);

尝试获取锁,若成功则返回 0;若锁已被占用,则立即返回 EBUSY,线程不会阻塞。

6.4 性能测量(时间获取)

int gettimeofday(struct timeval *tv, struct timezone *tz);

用法示例:

struct timeval start, end; gettimeofday(&start, NULL); // ... 临界区代码 ... gettimeofday(&end, NULL); // 计算耗时(秒 + 微秒) long seconds = end.tv_sec - start.tv_sec; long useconds = end.tv_usec - start.tv_usec; double elapsed = seconds + useconds / 1000000.0;

7. 自旋锁(Spin Lock)

概述:自旋锁是一种高性能、低延迟的互斥锁。当线程尝试获取锁失败时,不会进入休眠状态,而是在 CPU 上执行“忙等待”(Busy-waiting)循环,不断轮询直到锁被释放。

特点:

  • 消除了内核态上下文切换的开销。
  • 适用于临界区执行时间极短(纳秒/微秒级)的场景。
  • 若临界区执行时间较长,会浪费大量 CPU 资源。

初始化函数:pthread_spin_init

8. 读写锁(Read-Write Lock)

概述:读写锁是一种针对“读多写少”并发场景优化的锁机制。

基本原则:

  • 读读共享:多个线程可以同时持有读锁。
  • 读写互斥:读锁与写锁互斥。
  • 写写互斥:同一时间只能有一个线程持有写锁。

优势:在大量读取、少量更新的场景下,能显著提升系统吞吐量。

初始化函数:pthread_rwlock_init

9. 条件变量(Condition Variable)

概述:条件变量是一种线程同步机制,用于实现线程间的等待/通知模式。它允许线程在某个条件不满足时挂起等待,直到其他线程改变条件并发出通知。

核心函数:

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

功能:让当前线程休眠等待,直到某个特定条件成立(被其他线程唤醒)再继续执行。

调用时内部会按顺序做 3 件事:

  1. 解锁并休眠(原子操作):自动把传入的互斥锁 mutex 解锁,同时把当前线程放入 cond 的等待队列并让线程挂起休眠。
  2. 等待唤醒:线程处于阻塞状态,完全不消耗 CPU,直到其他线程发来唤醒信号。
  3. 被唤醒并重新加锁:被唤醒后,它会重新去抢 mutex 锁。抢锁成功后,pthread_cond_wait函数才会正式返回,继续往下执行代码。

典型使用模式:

// 1. 先加锁保护共享资源 pthread_mutex_lock(&mutex); // 2. 使用 while 检查条件(防止虚假唤醒) while (queue_is_empty) { // 条件不满足,解锁并进入休眠;被唤醒后自动重新加锁返回 pthread_cond_wait(&cond, &mutex); } // 3. 此时一定满足条件,且已经持有锁,安全地处理资源 pop_data_from_queue(); // 4. 操作完毕,解锁 pthread_mutex_unlock(&mutex);

相关函数:

  • int pthread_cond_signal(pthread_cond_t *cond);- 唤醒等待在该条件变量上的一个线程
  • int pthread_cond_broadcast(pthread_cond_t *cond);- 唤醒等待在该条件变量上的所有线程
  • int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);- 带超时的等待
http://www.jsqmd.com/news/1307751/

相关文章:

  • LC29H(XX) HAT RTK高精度定位:从厘米级原理到实战部署指南
  • 嘉兴买猫攻略:3 个核心维度筛选靠谱猫舍,新手避坑指南 - 滚动商讯
  • DeepSeek-Coder-V2完全部署指南:从本地搭建到生产级应用
  • 别把时间浪费在无脑操作上,三步操作3秒导出AI对话内容,直接带薪摸鱼!
  • Windows平台静态代码分析利器Understand:从安装配置到深度探索实战指南
  • 品牌如何从0到1搭建私域流量运营体系?
  • 破解激活难题:KMS智能脚本如何让Windows和Office重获新生?
  • 企业级AI化转型完整流程与AI+iPaaS工具选型指南
  • 工程数据资产管理踩坑实录,元启数宇对症下药
  • 2026大邑县吊车租赁公司推荐,高空车租赁公司推荐,三工鸟机械租赁一口价更安心 - geo88
  • 3/26打卡法:高效时间管理的黄金组合
  • macOS Catalina Patcher:让老旧Mac重获新生的终极解决方案
  • 2026年硕士毕业论文平台避坑实战报告:五家主流平台横向对比与学范文终极选型指南
  • 从直流有刷到伺服:5类电机工作原理、选型与应用全解析
  • BrainNet Viewer脑网络可视化:MATLAB科研绘图高效解决方案
  • Java线程池核心原理与高并发实战优化
  • 2026.8月 武汉洪山房屋漏水维修避坑指南,本地专业防水公司测漏流程、免砸砖施工优缺点详细解析 - 超人防水
  • Steam创意工坊模组下载终极指南:如何免费获取跨平台游戏的Steam模组
  • Live2D AI 网页助手完整解析:为你的网站添加智能动画小人
  • NHANES队列研究全流程实战:从数据清洗到生存分析
  • UNI.T成员社交媒体运营与个人发展策略分析
  • Obsidian i18n:突破语言障碍的智能化插件本地化方案
  • 2026天津考C2驾驶证驾校推荐,考手动挡驾驶证驾校推荐:沐安驾校口碑好 - geo88
  • 2026年助听器ODM供应链管理哪家强 - 滚动商讯
  • 黄祖鑫《御廷谣》热播中 以武术冠军功底锤炼少年将军底气
  • 猫抓cat-catch浏览器扩展:一键下载网页视频资源的终极指南
  • 基于Jetson Orin与ROS2的UGV自主移动机器人开发全流程解析
  • 风口专业!合肥中科信息工程学校新能源汽车专业,适合中考男生报考 - Luckyone王
  • 猫抓资源嗅探扩展:浏览器媒体捕获的终极架构实战
  • Qt | 四种方式实现多线程导出数据功能