linux线程 | 条件变量、信号量-ag九游会j9官方网站

ag九游会j9官方网站-j9九游会登录入口首页新版
linux线程 | 条件变量、信号量
2023-05-21
42 浏览

江海入海,知识涌动,这是我参与江海计划的第28篇。

1. 条件变量阻塞等待
条件变量不是锁,它经常和互斥量组合使用。以生产者消费者模型为例,当前有多个消费者线程竞争一个资源,当资源为空时,消费者线程会阻塞在一个条件上,等待生产者通知,生产者写数据到临界区并通知消费者,此时消费者去竞争这个资源并读取数据。它是这样实现的,第一个线程访问资源的时候,获得互斥锁,调用pthread_cond_wait将会释放锁,并阻塞在条件cond上面,这是第二个线程到来,依然可以获得互斥锁,然后这个线程如果调用pthread_cond_wait也会会释放锁,并阻塞在条件cond上面,这样,所有线程就都阻塞在cond上面。
头文件及函数原型
plain text
复制代码
#include
/*超时等待*/
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
/*条件变量阻塞等待*/
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
函数描述 the pthread_cond_timedwait() and pthread_cond_wait() functions shall block on a condition variable. they shall be called with mutex locked by the calling thread or undefined behavior results.
函数参数
cond:条件变量
mutex:互斥锁
abstime:是一个绝对时间,也就是1900年到现在的秒数(在stat函数中介绍过),如果我们要想设置abstime为10秒,应该先获取当前时间,并用这个时间加10,time(null) 10。
函数返回值 except in the case of [etimedout], all these error checks shall act as if they were performed immediately at the beginning of processing for the function and shall cause an error return, in effect, prior to modifying the state of the mutex specified by mutex or the condition variable specified by cond.
2. 初始化和销毁一个条件变量
头文件及函数原型
plain text
复制代码
#include
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
pthread_cond_t cond = pthread_cond_initializer;
函数描述
the pthread_cond_destroy() function shall destroy the given condition variable specified by cond; the object becomes, in effect, uninitialized.
the pthread_cond_init() function shall initialize the condition variable referenced by cond with attributes referenced by attr.
函数参数
cond:条件变量
attr:属性
函数返回值 if successful, the pthread_cond_destroy() and pthread_cond_init() functions shall return zero; otherwise, an error number shall be returned to indicate the error.
3. 唤醒阻塞在条件上的线程
头文件及函数原型
plain text
复制代码
#include
/*唤醒阻塞在条件变量cond上的全部线程*/
int pthread_cond_broadcast(pthread_cond_t *cond);
/*唤醒至少一个阻塞在条件上的线程*/
int pthread_cond_signal(pthread_cond_t *cond);
函数描述 these functions shall unblock threads blocked on a condition variable. 通俗讲就是发信号告诉阻塞在条件上的线程,可以去竞争资源了。
函数参数 cond:条件
函数返回值 if successful, the pthread_cond_broadcast() and pthread_cond_signal() functions shall return zero; otherwise, an error number shall be returned to indicate the error.
4. 生产者消费者模型
生产者消费者模型的实现程序:一个生产者,两个消费者

5. 什么是信号量
信号量相当于进化版的互斥锁。由于互斥锁的粒度比较大,如果我们希望在多个线程间对某一对象的部分数据进行共享,使用互斥锁是没有办法实现的,只能将整个数据对象锁住。这样虽然达到了多线程操作共享数据时保证数据正确性的目的,却无形中导致线程的并发性下降,线程从并行执行变成了串行执行,与直接使用单进程无异。信号量是相对折衷的一种处理方式,既能保证同步,数据不混乱,又能提高线程并发。
可以这么理解,比如说现在有一个资源可以允许三个线程同时访问,如果用互斥量的话,当第一个线程获取互斥锁的时候,后面的线程都会阻塞,这就无法实现三个线程同时访问资源了,会大大降低资源的利用效率。如果使用信号量,那个给信号量一个初值,每有一个线程访问到资源,信号量就减一,当减到0的时候,说明已经满足最多同时访问的线程数量了,后面的线程就不能再访问资源了,会阻塞。
6. 信号量相关api
6.1 初始化一个信号量
头文件及函数原型
函数描述 sem_init() initializes the unnamed semaphore at the address pointed to by sem. the value argument specifies the initial value for the semaphore.
函数参数
sem:传输参数,代表信号量,不能小于0。sem_t信号量数据类型,是一个结构体,可以简单理解为类似于文件描述符的东西。sem_t数据类型的实现是对用户隐藏的,所以在后面的 和–操作都是只能通过函数sem_wait和sem_post来实现。信号量的初值决定了占用信号量的线程的个数。
pshared:
0:用于线程间
非0:用于进程间
value:指定信号量初值
函数返回值 sem_init() returns 0 on success; on error, -1 is returned, and errno is set to indicate the error.
6.2 销毁一个信号量
头文件及函数原型
函数描述 sem_destroy() destroys the unnamed semaphore at the address pointed to by sem.
函数参数
sem
函数返回值 sem_destroy() returns 0 on success; on error, -1 is returned, and errno is set to indicate the error.
6.3 申请一个信号量(申请成功value–)
头文件及函数原型
函数描述
sem_wait() decrements (locks) the semaphore pointed to by sem. 信号量大于0,则信号量–,信号量等于0,则线程阻塞。
sem_trywait() is the same as sem_wait(), except that if the decrement can not be immediately performed, then call returns an error (errno set to eagain) instead of blocking.
sem_timedwait() is the same as sem_wait(), except that abs_timeout specifies a limit on the amount of time that the call should block if the decrement cannot be immediately performed.
函数参数
sem
函数返回值 all of these functions return 0 on success; on error, the value of the semaphore is left unchanged, -1 is returned, and errno is set to indicate the error.
6.4 释放信号量(value )
头文件及函数原型
函数描述 sem_post() increments (unlocks) the semaphore pointed to by sem. 信号量 ,同时唤醒阻塞在信号量上的线程。
函数参数
sem
函数返回值 sem_post() returns 0 on success; on error, the value of the semaphore is left unchanged, -1 is returned, and errno is set to indicate the error.
7. 信号量实现生产者消费者模型

avatarname
后发表内容
您的社区活跃积分 3,登录后即可领取  
网站地图