UNIX环境高级编程——线程同步之互斥锁、读写锁和条件变量(小结)
来源:互联网 发布:软件流程图实例 编辑:程序博客网 时间:2024/05/19 18:42
一、使用互斥锁
1、初始化互斥量
int pthread_mutex_init(pthread_mutex_t*mutex,pthread_mutexattr_t*attr);//动态初始化互斥量
int pthread_mutex_destory(pthread_mutex_t*mutex);//撤销互斥量
2、加锁和解锁互斥量
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t*mutex);
#include<stdio.h>
#include<semaphore.h>
#define NITERS 100000000
/*共享变量*/
unsigned int cnt = 0;
//sem_t mutex;
pthread_mutex_t mutex;
void *count(void *arg)
{
int i;
for(i=0;i<NITERS;i++)
{
pthread_mutex_lock(&mutex);
cnt++;
pthread_mutex_unlock(&mutex);
}
return arg;
}
int main()
{
pthread_t tid1,tid2;
int status;
pthread_mutex_init(&mutex,NULL);
pthread_mutex_destroy(&mutex);
if(cnt!=(unsigned)NITERS*2)
printf("Boom!,cnt=%d\n",cnt);
else
printf("Ok cnt=%d\n",cnt);
return 0;
}
3、使用多个互斥量
使用多个互斥量可能造成死锁问题。如下:
pthread_mutex_lock(&mutex_a); pthread_mutex_lock(&mutex_b);
pthread_mutex_lock(&mutex_b); pthread_mutex_lock(&mutex_a);
当两个线程都完成第一步时,都无法完成第二步,将造成死锁。可以通过以下两种方法来避免死锁:
固定加锁层次:所有需要同时加锁互斥量A和互斥量B的代码,必须先加锁A再加锁B。
试加锁和回退:在锁住第一个互斥量后,使用pthread_mutex_trylock来加锁其他互斥量,如果失败则将已加锁的互斥量释放,并重新加锁。
二、使用读写锁
通过读写锁,可以对受保护的共享资源进行并发读取和独占写入。读写锁是可以在读取或写入模式下锁定的单一实体。要修改资源,线程必须首先获取互斥写锁。必须释放所有读锁之后,才允许使用互斥写锁。
1. 初始化和销毁:
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
同互斥量一样, 在释放读写锁占用的内存之前, 需要先通过pthread_rwlock_destroy对读写锁进行清理工作, 释放由init分配的资源.
2.加锁和解锁
读取非阻塞读写锁中的锁 int pthread_rwlock_tryrdlock(pthread_rwlock_t*rwlock);
写入读写锁中的锁 int pthread_rwlock_wrlock(pthread_rwlock_t*rwlock);
写入非阻塞读写锁中的锁 int pthread_rwlock_trywrlock(pthread_rwlock_t*rwlock);
解除锁定读写锁 int pthread_rwlock_unlock(pthread_rwlock_t*rwlock);
三、条件变量
假如某个线程需要等待系统处于某种状态下才能继续执行,Linux为了解决这种问题引入了条件变量这种线程同步对象,条件变量是用来通知共享数据状态信息的,等待条件变量总是返回锁住的互斥量,条件变量是与互斥量相关、也与互斥量保护的共享数据相关的信号机制。
条件变量不提供互斥,需要一个互斥量来同步对共享数据的访问,这就是为什么在等待条件变量时必须指定一个互斥量。
1、创建和销毁条件变量
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
2、等待条件变量
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);
两个函数的差别在于前者指定一个超时时间,在该时间内阻塞调用线程,并等待条件变量,如果规定时间内条件还没有发生,则函数返回。每个条件变量必须一个特定互斥量关联,当线程等待条件变量时,他必须将相关互斥量锁住。在阻塞线程之前,条件变量等待操作将解锁互斥量,而在重新返回线程之前,会在次锁住互斥量。
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
- UNIX环境高级编程——线程同步之互斥锁、读写锁和条件变量(小结)
- UNIX环境高级编程——线程同步之互斥锁、读写锁和条件变量(小结)
- UNIX环境高级编程——线程同步之条件变量以及属性
- UNIX环境高级编程——线程同步之条件变量以及属性
- UNIX环境高级编程——线程同步之读写锁以及属性
- UNIX环境高级编程——线程同步之读写锁以及属性
- UNIX环境高级编程——线程同步之互斥量
- 线程同步之互斥锁、读写锁和条件变量
- 《unix高级环境编程》线程——线程同步
- 《unix高级环境编程》线程——线程同步
- Windows核心编程之 用户模式下的线程同步 读写锁和条件变量
- UNIX环境高级编程学习之第十一章线程-使用条件变量
- (四十三)线程——线程同步(互斥锁、读写锁、条件变量、信号量)
- unix环境高级编程——线程同步信号
- 《unix高级环境编程》线程控制——同步属性
- 《unix高级环境编程》线程控制——同步属性
- UNIX环境高级编程——线程同步之互斥量 && 死锁
- linux多线程学习笔记四---线程同步之互斥锁、读写锁和条件变量
- tat函数说明
- Data guard常用视图
- 黑马程序员-7K面试之二交通灯管理
- STM32F407学习之GPIO
- C++访问控制
- UNIX环境高级编程——线程同步之互斥锁、读写锁和条件变量(小结)
- 解决listview中出现重复的项
- 为什么每次打开Myeclipse都要重新配置Tomcat
- 按键配置文件位置
- 数据挖掘的常见方法
- Hud 1856 More is Better[并查集]
- 取扩展名
- Template模版实例(C++)
- 指向指针的指针