• ioftpd read/write 锁实现


    //z ioftpd read/write 锁实现
    //z 2014-05-09 18:05:41 L.236'21259 BG57IV3@XCL T3344801563.K.F1390913624[T5,L93,R3,V252]
    #define LOCK_MAX_COUNT	10000
    
    typedef struct _LOCKOBJECT
    {
    	HANDLE			hEvent[2];
    	LONG volatile	lExclusive;
    } LOCKOBJECT, *LPLOCKOBJECT;
    
    VOID ReleaseExclusiveLock(LPLOCKOBJECT lpLockObject);
    VOID AcquireExclusiveLock(LPLOCKOBJECT lpLockObject);
    VOID ReleaseSharedLock(LPLOCKOBJECT lpLockObject);
    VOID AcquireSharedLock(LPLOCKOBJECT lpLockObject);
    VOID DeleteLockObject(LPLOCKOBJECT lpLockObject);
    BOOL InitializeLockObject(LPLOCKOBJECT lpLockObject);
    
    //z 2014-05-09 16:53:25 L.236'25595 T1731279863.K[T3,L97,R3,V51]
    //z 初始化。
    BOOL InitializeLockObject(LPLOCKOBJECT lpLockObject)
    {
    	//z 默认不是排他的
    	lpLockObject->lExclusive	= FALSE;
    	//z Event,人工重置事件,初始化状态为已通知。
    	lpLockObject->hEvent[0]	= CreateEvent(NULL, TRUE, TRUE, NULL);
    	if (lpLockObject->hEvent[0] == INVALID_HANDLE_VALUE) return FALSE;
    	
    	//z 用于 share 锁,控制reader数量
    	lpLockObject->hEvent[1]	= CreateSemaphore(NULL, LOCK_MAX_COUNT, LOCK_MAX_COUNT, 0);
    	if (!lpLockObject->hEvent[1])
    	{
    		CloseHandle(lpLockObject->hEvent[0]);
    		lpLockObject->hEvent[0] = INVALID_HANDLE_VALUE;
    		return FALSE;
    	}
    	return TRUE;
    }
    
    //dtor
    VOID DeleteLockObject(LPLOCKOBJECT lpLockObject)
    {
    	HANDLE hEvent;
    
    	hEvent = lpLockObject->hEvent[0];
    	//z 关闭 event;做一些必要的检测
    	if (hEvent && (hEvent != INVALID_HANDLE_VALUE))
    	{
    		CloseHandle(hEvent);
    	}
    	//z 关闭后,将其设置为 INVALID_HANDLE_VALUE
    	lpLockObject->hEvent[0] = INVALID_HANDLE_VALUE;
    
    	hEvent = lpLockObject->hEvent[1];
    	if (hEvent && (hEvent != INVALID_HANDLE_VALUE))
    	{
    		CloseHandle(hEvent);
    	}
    	lpLockObject->hEvent[1] = INVALID_HANDLE_VALUE;
    }
    
    //z 获取共享锁。
    VOID AcquireSharedLock(LPLOCKOBJECT lpLockObject)
    {
    	//z 得同时在这两个 event 上等待
    	//z 在人工重置事件上等待成功后,没有变更其状态,等待成功之后,还是已通知状态。
    	//z 由semaphore来控制read的数量。
    	WaitForMultipleObjects(2, lpLockObject->hEvent, TRUE, INFINITE);
    }
    
    //z 释放shared lock
    VOID ReleaseSharedLock(LPLOCKOBJECT lpLockObject)
    {
    	ReleaseSemaphore(lpLockObject->hEvent[1], 1, NULL);
    }
    
    //z 获取排它锁
    VOID AcquireExclusiveLock(LPLOCKOBJECT lpLockObject)
    {
    	LONG	lCount, lLeft;
    
    	//z 获取排他性,如果此时 lExclusive 为true,那么其已经被其他排它锁持有,那么就在其上等待
    	while (InterlockedExchange(&lpLockObject->lExclusive, TRUE)) WaitForSingleObject(lpLockObject->hEvent[0], INFINITE);
    	//z 当前 lExclusive 为 false 或者其他排它锁释放了该锁(重置为已通知状态)。
    	//z 获取排它锁成功;将event置为未通知状态。这样其他排它锁无法获取。
    	ResetEvent(lpLockObject->hEvent[0]);
    	
    	//z 然后在读取锁上等待;既然是排他的,那么read锁也得排除,可能更改内容
    	for (;;)
    	{
    		//z 这个等待主要是为了获取下一句 lCount
    		//z 在count大于0时,为已通知状态。等待成功,则count减少1。
    		WaitForSingleObject(lpLockObject->hEvent[1], INFINITE);
    		//z count 增加1,lCount获取之前的 count 数目。加上这个释放的,现在一共有 (lCount+1)个
    		ReleaseSemaphore(lpLockObject->hEvent[1], 1, &lCount);
    		//z 还剩下多少需要等待
    		lLeft	= (LOCK_MAX_COUNT - 1) - lCount;
    		//z 没有需要等待的,获取排它锁成功
    		if (! lLeft) break;
    		
    		//z 放弃时间片
    		if (lLeft < 10)
    		{
    			//z SwitchToThread():只要有可调度线程,即便优先级较低,也会让其调度。
    			SwitchToThread();
    		}
    		//z sleep ,放弃线程拥有的剩余时间片;与上述区别是 Sleep(0):时间片只能让给优先级相同或更高的线程;
    		else Sleep(10);
    	}
    }
    
    VOID ReleaseExclusiveLock(LPLOCKOBJECT lpLockObject)
    {
    	//z 注意与上述获取排它锁的过程的顺序对比下。
    	//z 先重置事件为通知状态
    	SetEvent(lpLockObject->hEvent[0]);
    	//z 设置 lExclusive 为 FALSE,以供其他等待的排它锁可用。
    	InterlockedExchange(&lpLockObject->lExclusive, FALSE);
    }
    



    @IS2120#CNBLOGS.T2169364049[T1,L65,R1,V259]:备忘
    $ € ₤ ₭ ₪ ₩ ₮ ₦ ₱ ฿ ₡ ₫ ﷼ ¥ ﷼ ₫ ₡ ฿ ₱ ₦ ₮ ₩ ₪ ₭ ₤ € $
  • 相关阅读:
    DataTable转Json就是这么简单(Json.Net DLL (Newtonsoft))
    Mysql查询数据库 整理
    Mysq基础l数据库管理、表管理、增删改数据整理
    zTree基础
    ECharts基础
    layui基础总结
    Bootstrap基础
    JQuery进阶
    JQuery基础总结
    Javascript鼠标键盘事件
  • 原文地址:https://www.cnblogs.com/IS2120/p/6745662.html
Copyright © 2020-2023  润新知