Pthread定时锁与读写锁详解
目录
1.pthread_mutex_timedlock函数的优势
2.pthread_mutex_timedlock是如何避免无限期的阻塞
3.读写锁
4.读写锁的使用示例
1.pthread_mutex_timedlock函数的优势
- 可控的阻塞时长:可以指定一个超时时间,如果在该时间内未能获得锁,则返回ETIMEDOUT并退出阻塞。相比trylock手动实现超时,更简洁且原子性更强
- 平衡等待与响应性:既可以在一定时间内等待锁释放(适合需要最终获取锁的场景。即使可以用trylock非阻塞式的锁,可以使得程序继续运转,但若是我们要求该程序必须要获得锁上的资源,那么timedlock明显是更好的选择)。适合对实时性有要求的场景,确保线程在规定时间内要么获得锁,要么执行超时处理
- 简化超时逻辑:无需像trylock那样通过循环 + 睡眠实现超时,减少用户态代码复杂性,且底层实现更高效
pthread_mutex_timedlock函数基本等价于pthread_mutex_lock函数,但是如果超过了自己所设定的时间,pthread_mutex_timedlock函数不会锁定互斥量,但会返回错误码
返回值:成功则为0,失败则为错误码
struct timespec {time_t tv_sec; // 秒数(自纪元以来的秒数)long tv_nsec; // 纳秒数(0-999,999,999)
};
2.pthread_mutex_timedlock是如何避免无限期的阻塞
#include <pthread.h>
#include <time.h>
#include <iostream>
#include <stdlib.h>
#include <cstring>
int main()
{int err;struct timespec tout;struct tm *tmp;char buf[64];pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_lock(&lock);std::cout << "mutex is lock" << std::endl;clock_gettime(CLOCK_REALTIME, &tout);tmp = localtime(&tout.tv_sec);strftime(buf, sizeof(buf), "%r", tmp);std::cout << "current time is " << buf << std::endl;tout.tv_sec += 10; // 10秒以后err = pthread_mutex_timedlock(&lock, &tout);clock_gettime(CLOCK_REALTIME, &tout);tmp = localtime(&tout.tv_sec);strftime(buf, sizeof(buf), "%r", tmp);std::cout << "current time is " << buf << std::endl;if(err == 0)std::cout<<"mutex locked again!"<<std::cout;elsestd::cout<<"can't lock mutex again :"<<strerror(err);return 0;
}
3.读写锁
读写锁类似于互斥量,不同之处在于它允许更高的并行性。读写锁可能有三种状态:读模式锁定、写模式锁定和未锁定。一次只能有一个线程在写模式下持有读写锁,但多个线程可以同时在读模式下持有读写锁。
虽然各种实现对读写锁的实现方式有所不同,但如果锁已在读模式下被持有,并且一个线程在试图以写模式获取该锁时被阻塞,则读写锁通常会阻止其他读者。这可以防止源源不断的读者让等待的写者感到饥饿。
适用环境:读写锁非常适合对数据结构的读取频率高于修改频率的情况
要以读模式锁定读写锁,需要调用pthread_rwlock_rdlock函数。要以写模式锁定读写锁,则需要调用pthread_rwlock_wrlock函数。无论如何锁定一个读写锁,都可以通过调用pthread_rwlock_unlock函数来解锁它
4.读写锁的使用示例
#include <pthread.h>
#include <time.h>
#include <iostream>
#include <stdlib.h>
#include <cstring>
int main()
{int err;struct timespec tout;struct tm *tmp;char buf[64];pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_lock(&lock);std::cout << "mutex is lock" << std::endl;clock_gettime(CLOCK_REALTIME, &tout);tmp = localtime(&tout.tv_sec);strftime(buf, sizeof(buf), "%r", tmp);std::cout << "current time is " << buf << std::endl;tout.tv_sec += 10; // 10秒以后err = pthread_mutex_timedlock(&lock, &tout);clock_gettime(CLOCK_REALTIME, &tout);tmp = localtime(&tout.tv_sec);strftime(buf, sizeof(buf), "%r", tmp);std::cout << "current time is " << buf << std::endl;if(err == 0)std::cout<<"mutex locked again!"<<std::cout;elsestd::cout<<"can't lock mutex again :"<<strerror(err);return 0;
}