【学习总结】线程间锁机制

本文详细介绍了Windows操作系统中的多种同步机制,包括临界区、互斥锁、信号量、事件对象等,并探讨了它们的使用场景及优缺点。此外,还介绍了原子锁、嵌套锁、无锁队列、读写锁等高级同步手段,以及线程池的设计理念。
摘要由CSDN通过智能技术生成


windows锁

临界区:InitializeCriticalSection() / EnterCriticalSection() / LeaveCriticalSection() / DeleteCriticalSection()

互斥锁:CreateMutex() / OpenMutex() / ReleaseMutex (有名字,可以被不同进程使用,获取锁和释放锁的必须是同一个线程)

信号量:CreateSemaphore() / OpenSemaphore() / ReleaseSemaphore  (可以保护多个资源。可以被不同的thread加锁解锁)

event对象:main thread 进行event设置和操作:CreateEvent() / SetEvent() / WaitForMultiObjects() / CloseHandle()    normal thread等待event: WaitForSingleObject()(在tread获得锁的使用权之前main thread要调用SetEvent设置一把)

使用频率:信号量 > 互斥区 > 临界区 > event

使用c++特性将EnterCriticalSection() 函数放入类的构造函数中,将LeaveCriticalSection() 放入类的析构函数中,可以实现实例创建时自动进行临界区pk,实例被各种情况销毁时撤销锁

原子锁(InterLocked)

嵌套锁(解决在申请使用公共数据时,数据自身带加锁机制导致使用的调用程序重复加锁造成的获取资源失败的情况)

//嵌套锁结构
typedef struct _NestLock  //嵌套锁结构
{
        int threadId;   //上锁进程号
        int count;          //锁数量
        HANDLE hLock;     //锁信号量
}NestLock;

实现:

( NestLock *) create_nest_lock(HANDLE hLock) //嵌套锁create
{
	NestLock *hNestLock; 
	hNestLock = (NestLock*)malloc(sizeof(NestLock));
	assert( NULL != hNestLock );

	hNestLock->threadId = hNestLock->count = 0;
	hNestLock->hLock = hLock;
	return hNestLock;
}

void get_nest_lock( NestLock *hNestLock)        //申请嵌套锁
{
	assert(NULL != hNestLock);

	if( hNestLock->threadId == GetThreadId() )              //资源已被锁并且被当前线程锁,走嵌套锁流程
	{
		hNestLock->count ++;
	}else{                          //资源没被锁或被其他线程锁,走正常申请锁流程
		WaitForSingleObject( hNestLock->hLock );
		hNestLock->count = 1;
		hNestLock->threadId = GetThreadID();
	}

}

void release_nest_lock( NestLock *hNestLock )         //释放嵌套锁
{
	assert( NULL != hNestLock );
	assert( GetThreadId() == hNestLock->threadId );
	
	hNestLock->count--;
	if( 0 == hNestLock->count )              //当前为资源上的最后一个锁
	{
		hNestLock->threadId = 0;
		ReleaseMutex( hNestLock->hLock );
	}
}

无锁队列(队列具有天生的互斥性能)

队列先入先出的机制具有先天的互斥性能,一个线程入队列操作,一个线程出队列操作并不会对队列中内容造成混乱

如可以将队列作为job队列进行多进程任务分配

读写锁(多读少写的情况下,读读锁不互斥,写写锁互斥,读写锁互斥)

typedef struct _RWlOCK
{
	int count;     //锁数量
	int state;      //枚举类型(读,写,无锁)
	HANDLE hRead;    //读锁信号量
	HANDLE hWrite;     //写锁信号量
}RWLock;




typedef enum  //枚举类型用来记录锁状态
{
	STATE_EMPTY = 0,      //没有锁
	STATE_READ,           //读锁
	STATE_WRITE           //写锁
};

获取读锁操作:wait for读锁信号量 -> wait for写锁信号量,修改锁状态为STATE_READ( 如果是第一次得到读锁 ) -> count++ -> 释放读锁信号量

获取写锁操作:申请写锁 -> count++ ->修改写锁状态为STATE_READ

释放读锁(和获取读锁对应):申请读锁 -> count-- ->修改锁状态为STATE_EMPTY , 释放写锁信号(如果是最后一把读锁) -> 释放读锁信号

顺序锁(对读写锁进行改进,解决读锁导致写锁一直等待的问题)

读锁不对信号量进行任何操作,通过sequence进行读锁的使用,有可能边写边读

无锁链表(对顺序锁的改进,解决处理的数据不能为指针的问题)


线程池(一次申请多个线程,通过任务队列进行调度,线程池中的线程一次init,中间只有启用和回收,进程结束统一销毁线程池,缓解了线程频繁创建和销毁造成的时间浪费)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值