博客
关于我
pthread_cond_t 和 pthread_mutex_t
阅读量:798 次
发布时间:2023-03-31

本文共 1810 字,大约阅读时间需要 6 分钟。

条件变量是一种在多线程环境中用于同步的机制,通过共享全局变量实现线程间的一致性操作。其主要功能是允许一个线程等待某个条件满足而暂停(条件等待),另一个线程则可以给予条件满足信号(激发条件)。为了防止竞争条件的产生,条件变量的使用通常与互斥锁结合使用。

1. 创建和注销条件变量

条件变量的创建和销毁与互斥锁类似,提供了静态和动态两种方式:

  • 静态创建:通过PTHREAD_COND_INITIALIZER常量初始化条件变量。例如:

    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  • 动态创建:调用pthread_cond_init()函数,API定义如下:

    int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

    在LinuxThreads实现中,cond_attr通常为NULL且被忽略。条件变量没有属性资源,因此注销时只需检查是否有线程正在等待该条件。

  • 注销条件变量:调用pthread_cond_destroy(),API如下:

    int pthread_cond_destroy(pthread_cond_t *cond);

    注销成功的条件是没有线程正在等待该条件,否则返回EBUSY。

2. 条件等待与激发

条件变量的等待和激发操作如下:

  • 无条件等待pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

  • 计时等待pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)

pthread_cond_waitpthread_cond_timedwait都需要与一个互斥锁配合使用,以防止竞争条件。互斥锁必须是PTHREAD_MUTEX_TIMED_NPPTHREAD_MUTEX_ADAPTIVE_NP类型,且在调用等待函数前必须由本线程加锁。互斥锁在条件满足时会被重新加锁,以确保线程进入等待前的加锁动作得到对应。

  • 激发条件pthread_cond_signal(pthread_cond_t *cond)激活一个等待该条件的线程,pthread_cond_broadcast(pthread_cond_t *cond)激活所有等待该条件的线程。

典型应用示例

考虑以下场景:两个线程A和B分别执行decrement_countincrement_count函数,管理一个计数器count。假设线程A首先执行decrement_count

#include 
#include
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;unsigned count = 0;void decrement_count() { pthread_mutex_lock(&mtx); while (count == 0) { pthread_cond_wait(&cond, &mtx); } count--; pthread_mutex_unlock(&mtx);}

线程B执行increment_count

void increment_count() {    pthread_mutex_lock(&mtx);    if (count == 0) {        pthread_cond_signal(&cond);    }    count++;    pthread_mutex_unlock(&mtx);}

在这种设计中:

  • 线程A通过pthread_cond_wait被阻塞至count不为零。
  • 线程B在count为零时激活条件,唤醒线程A。
  • 线程A随后获得互斥锁,减少count并解锁。
  • 线程B增加count并解锁。

这种设计确保了计数器的正确性和线程安全,避免了竞争和死锁。

转载地址:http://kpefk.baihongyu.com/

你可能感兴趣的文章
OSG学习:纹理映射(三)——立方图纹理映射
查看>>
OSG学习:纹理映射(二)——一维/二维/简单立方图纹理映射
查看>>
OSG学习:纹理映射(五)——计算纹理坐标
查看>>
OSG学习:纹理映射(六)——灯光
查看>>
OSG学习:纹理映射(四)——三维纹理映射
查看>>
OSG:从源码看Viewer::run() 一
查看>>
osi 负载均衡
查看>>
OSI七层模型与TCP/IP五层模型(转)
查看>>
OSI七层模型与TCP/IP四层与五层模型详解
查看>>
OSI七层模型的TCP/IP模型都有哪几层和他们的对应关系?
查看>>
OSI操作系统(NETBASE第八课)
查看>>
OSM数据如何下载使用(地图数据篇.11)
查看>>
OSPF 四种设备角色:IR、ABR、BR、ASBR
查看>>
OSPF 四种路由类型:Intra Area、Inter Area、第一、二类外部路由
查看>>
OSPF 学习
查看>>
OSPF 支持的网络类型:广播、NBMA、P2MP和P2P类型
查看>>
OSPF 概念型问题
查看>>
OSPF 的主要目的是什么?
查看>>
OSPF5种报文:Hello报文、DD报文、LSR报文、LSU报文和LSAck报文
查看>>
SQL Server 存储过程分页。
查看>>