博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
experiment: 锁操作
阅读量:1992 次
发布时间:2019-04-27

本文共 9507 字,大约阅读时间需要 31 分钟。

简单锁: CSimpleLock, CAutoCritic

  在<<Advanced Logging for all kind of applications>>中发现了简单锁, codeproject上很多文章都提到了这种锁, 实现思路基本相同. 用起来很简洁.

original url:

Advanced Logging for all kind of applications

http://www.codeproject.com/KB/debug/alx_log.aspx

<2011_1006>

今天在日志类重构中用到了自动锁.

 original url from : http://www.codeproject.com/KB/threads/stkmutex.aspx?display=Mobile

A heap or shared memory based mutex pool manager

只用到了其中的自动锁.

修改后, 根据不同的日志 全路径名称生成不同的日志锁名. 保证操作每一个日志,都有唯一的一把日志锁~, 这种日志锁基于 CreateMutexW, 可以跨进程.

// srcSocketOPTServer.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#include
#include
#include
#include "socket/SocketCommServer.h"#include "LOg/DebugLog.h"CDebugLog * pDebugLog = NULL;int _tmain(int argc, _TCHAR* argv[]){ _tsetlocale(LC_ALL, _T("Chinese_People's Republic of China.936")); pDebugLog = new CDebugLog(_T("c:\\SocketOPTServer.txt")); if(!pDebugLog) { _tprintf(_T("error : new CDebugLog\n")); } TRACE_CODE_INFO(pDebugLog, _T(">> _tmain")); /** 日志效果 * <18:36:05><3768-428>
<24> [wmain][>> _tmain] */ CSocketCommServer SockServer; if(S_OK != SoketEnvironmentBegin()) goto END; if(!SockServer.Connect(_T("50000"), TRUE)) { _tprintf(_T("服务器连接建立失败\n")); goto END; } do { _tprintf(_T("按'q'键退出程序\n")); Sleep(100); }while(_T('q') != getchar()); SockServer.DisConnect();END: SoketEnvironmentEnd(); if(pDebugLog) { delete pDebugLog; pDebugLog = NULL; } getchar(); return 0;}
/*** @file DebugLog.h* @brief 调试日志*/#ifndef __DEBUGLOG_H__#define __DEBUGLOG_H__#include 
#ifndef tstring #ifdef _UNICODE #define tstring std::wstring #else #define tstring std::string #endif #endif #ifndef WIDEN2#define WIDEN2(x) L ## x#define WIDEN(x) WIDEN2(x)#define __WFILE__ WIDEN(__FILE__)#define __WLINE__ __LINE__#define __WFUNCTION__ WIDEN(__FUNCTION__)#define TRACE_CODE_INFO(pDebugLog, strMsg) \{\tstring strFun = __WFUNCTION__;\tstring strPathName = __WFILE__;\if(strPathName.size() > 80)\{\ strPathName = strPathName.substr(strPathName.size() - 1 - 80, strPathName.size() - 1);\}\pDebugLog->logv(_T("<%s><%d> [%s][%s]\n"), strPathName.c_str(), __WLINE__, strFun.c_str(), strMsg);\}#endif /**< #ifndef WIDEN2 */#define G_SIZE_LOG_BUF (INT)4096#include "Locker/SysMutex.h"class STK::CSysMutex;class CDebugLog{public: CDebugLog(CONST TCHAR * pLogPathName); virtual ~CDebugLog(); VOID logv(TCHAR * szFormat, ...); VOID log(TCHAR * pPathName, TCHAR * szFormat);private: VOID InitLock(); VOID UnInitLock(); INT CreateLogFileIfNotExsit(TCHAR * pPathName);private: STK::CSysMutex* m_pSysMutexLog; TCHAR m_cLogPathName[_MAX_PATH]; TCHAR m_cLockerName[20 + 1];};#endif /**< #define __DEBUGLOG_H__ */
/*** @file DebugLog.cpp* @brief 调试日志实现*/#include "stdafx.h"#include 
#include
#include
#include
#include
#include
/**< for va_list */#include
#include
#include "DebugLog.h"#include "Locker/AutoLock.h"#include "openssl/sha.h"#pragma comment(lib, "libeay32.lib")#pragma comment(lib, "ssleay32.lib")class CAutoLock;CDebugLog::CDebugLog(CONST TCHAR * pLogPathName){ ZeroMemory(m_cLogPathName, sizeof(m_cLogPathName)); ZeroMemory(m_cLockerName, sizeof(m_cLockerName)); _tcscpy_s(m_cLogPathName, sizeof(m_cLogPathName) / sizeof(TCHAR), pLogPathName); /** 根据日志全路径生成唯一的锁名称, 保证操作每一个日志文件都有一把相同的锁 */ SHA1((const unsigned char *)m_cLogPathName, sizeof(m_cLogPathName) / sizeof(TCHAR), (unsigned char *)m_cLockerName); m_pSysMutexLog = NULL; InitLock();}CDebugLog::~CDebugLog(){ UnInitLock();}VOID CDebugLog::InitLock(){ if(!m_pSysMutexLog) { m_pSysMutexLog = new (std::nothrow) STK::CSysMutex(FALSE, m_cLockerName , NULL); }}VOID CDebugLog::UnInitLock(){ if(m_pSysMutexLog) { m_pSysMutexLog->Unlock(); /** Free the system mutex */ delete m_pSysMutexLog; m_pSysMutexLog = NULL; }}INT CDebugLog::CreateLogFileIfNotExsit(TCHAR * pPathName){ errno_t err = 0; FILE * pFile = NULL; HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATA FindFileData; STK::CAutoLock
lockAuto(m_pSysMutexLog); hFind = ::FindFirstFile(pPathName, &FindFileData); if(INVALID_HANDLE_VALUE == hFind) { /** not find log file, create it */ err = _tfopen_s(&pFile, pPathName, _T("wb")); _ASSERT(0 == err); if(pFile) { fclose(pFile); pFile = NULL; } } return S_OK;}VOID CDebugLog::logv(TCHAR * szFormat, ...){ STK::CAutoLock
lockAuto(m_pSysMutexLog); va_list args; va_start(args, szFormat); TCHAR * pBufMsg = new TCHAR[G_SIZE_LOG_BUF]; _ASSERT(pBufMsg); ZeroMemory(pBufMsg, G_SIZE_LOG_BUF * sizeof(TCHAR)); int nRc = 0; nRc = _vsntprintf_s(pBufMsg, G_SIZE_LOG_BUF, _TRUNCATE, szFormat, args); _ASSERT(G_SIZE_LOG_BUF > nRc); va_end(args); log(m_cLogPathName, pBufMsg); delete pBufMsg; pBufMsg = NULL;}VOID CDebugLog::log(TCHAR * pPathName, TCHAR * szFormat){ errno_t err = 0; FILE * pFile = NULL; SYSTEMTIME tm; TCHAR * pBufMsg = new TCHAR[G_SIZE_LOG_BUF]; _ASSERT(pBufMsg); ZeroMemory(pBufMsg, G_SIZE_LOG_BUF * sizeof(TCHAR)); err = _tfopen_s(&pFile, pPathName, _T("ab+")); _ASSERT(0 == err); if(pFile) { ::GetLocalTime(&tm); _stprintf_s(pBufMsg, G_SIZE_LOG_BUF, _T("<%2.2d:%2.2d:%2.2d><%d-%d> %s\r\n"), tm.wHour, tm.wMinute, tm.wSecond, ::GetCurrentProcessId(), ::GetCurrentThreadId(), szFormat); fwrite(pBufMsg, sizeof(TCHAR), _tcslen(pBufMsg), pFile); fclose(pFile); pFile = NULL; } if(pBufMsg) { delete pBufMsg; pBufMsg = NULL; }}
#pragma once/*** original from : http://www.codeproject.com/KB/threads/stkmutex.aspx?display=Mobile*/#include 
namespace STK{class CSysMutex{public: CSysMutex(bool bInitiallyOwn = false, TCHAR * pszName = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL); virtual ~CSysMutex();public: bool Lock(DWORD dwTime); bool Unlock();private: bool Create(bool bInitiallyOwn = false, TCHAR * pszName = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL); bool Release();private: HANDLE m_hMutex;};}
#include "stdafx.h"#include "SysMutex.h"namespace STK{CSysMutex::CSysMutex(bool bInitiallyOwn, TCHAR * pszName, LPSECURITY_ATTRIBUTES lpsaAttribute)    : m_hMutex(NULL){    Create(bInitiallyOwn, pszName, lpsaAttribute);}CSysMutex::~CSysMutex(){    Release();}bool CSysMutex::Unlock(){    if (m_hMutex == NULL)    {        return false;    }	return (::ReleaseMutex(m_hMutex) == TRUE);}bool CSysMutex::Lock(DWORD dwTimeout){    if (m_hMutex == NULL)    {        return false;    }	DWORD dwRet = ::WaitForSingleObject(m_hMutex, dwTimeout);	if ((dwRet == WAIT_OBJECT_0) ||         (dwRet == WAIT_ABANDONED))    {		return true;    }	else    {		return false;    }}bool CSysMutex::Create(bool bInitiallyOwn, TCHAR * pszName, LPSECURITY_ATTRIBUTES lpsaAttribute){    Release();	m_hMutex = ::CreateMutexW(lpsaAttribute, bInitiallyOwn, pszName);    if (m_hMutex == NULL)    {        return false;    }    return true;}bool CSysMutex::Release(){    BOOL bRet = TRUE;	if (m_hMutex != NULL)	{		bRet = ::CloseHandle(m_hMutex);		m_hMutex = NULL;	}    return (bRet == TRUE);}}
#pragma once#include 
#include
#include
#include
namespace STK{template
class CAutoLock{public: CAutoLock(T *pLock) { if (pLock) { m_pLock = pLock; m_pLock->Lock(INFINITE); } } virtual ~CAutoLock() { if (m_pLock) { m_pLock->Unlock(); m_pLock = NULL; } }private: T* m_pLock;};}

整理了CDebugLog的用法

/*** @file srcLockerOnLogOpt.cpp* @brief environment: vs2005 + unicode + winxpSp3 + openssl* @note 演示了在日志操作中使用自动锁, 演示了如何使每个日志文件对应与一把自动锁*/#include "stdafx.h"#include 
#include
#include
#include
#include "Log/DebugLog.h"CDebugLog * pDebugLog = NULL;int _tmain(int argc, _TCHAR* argv[]){ _tsetlocale(LC_ALL, _T("Chinese_People's Republic of China.936")); pDebugLog = new CDebugLog(_T("c:\\LockerOnLogOpt.txt")); if(!pDebugLog) { _tprintf(_T("error : new CDebugLog\n")); goto END; } _tprintf(_T("ready log some thing\n")); TRACE_CODE_INFO(pDebugLog, _T(">> _tmain")); _tprintf(_T("log end\n")); /** log other log after pDebugLog is NOT NULL */END: if(pDebugLog) { delete pDebugLog; pDebugLog = NULL; } _tprintf(_T("press any to quit\n")); getchar(); /** 运行效果 * ready log some thing * log end * press any to quit */ /** 日志效果 * <19:11:11><3932-2320>
<28> [wmain][>> _tmain] */ return 0;}
工程文件包含关系:

demo upload : 

<2011_1119>

线程锁的Demo

// srcThreadLocker.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#include
#include
#include
#include "ThreadLocker/ls_threadlock.h"void ThreadFn_Worker(PVOID pParam);void ThreadFn_CheckKey(PVOID pParam);BOOL bStop;int _tmain(int argc, _TCHAR* argv[]){ bStop = FALSE; CLsMutex Mutex; _beginthread(ThreadFn_Worker, 0, &Mutex); _beginthread(ThreadFn_Worker, 0, &Mutex); _beginthread(ThreadFn_Worker, 0, &Mutex); _beginthread(ThreadFn_CheckKey, 0, NULL); while(!bStop) { Sleep(100); } _tprintf(_T("END, press any key to quit\n")); /**
=<0x9CC>
=<0x99C>
=<0x358>
=<0x9CC> Stop Command Happen
=<0x99C>
=<0x358>
=<0x%X>\n"), _T("ThreadFn_Worker"), dwThreadId); Sleep(10); }END: _tprintf(_T("<%s[0x%X]\n"), _T("Quit ThreadFn_Worker"), dwThreadId);}void ThreadFn_CheckKey(PVOID pParam){ getchar(); bStop = TRUE; _tprintf(_T("Stop Command Happen\n"));}

转载地址:http://helvf.baihongyu.com/

你可能感兴趣的文章
油猴脚本:微信推送浏览功能拓展
查看>>
JavaScript 表单操作与MD5加密
查看>>
JAVA学习笔记4 - 循环与分支结构
查看>>
JAVA学习笔记5 - Number类,Math类,Character类,String类,StringBuffer类
查看>>
JAVA学习笔记6 - 数组
查看>>
JAVA学习笔记8 - Stream 和 File I/O
查看>>
JAVA学习笔记9 - 异常
查看>>
JAVA学习笔记10 - 继承
查看>>
JAVA学习笔记11 - 接口interface
查看>>
Android 开发学习笔记 00 - Getting Started
查看>>
【学习笔记】Android Activity
查看>>
Android使用Retrofit_00_Getting Started
查看>>
Android使用Retrofit_01_OAuth2 + GitHub
查看>>
Django oauth toolkit + Android + Retrofit 实现 OAuth2 的 access token 获取
查看>>
Android + Django + OAuth2 + Stub Authenticator
查看>>
Django + REST学习笔记
查看>>
Android Sync Adapter (使用Stub Content Provider) 笔记
查看>>
诡异的 Scroll view may have only one direct child placed within it 错误
查看>>
【转载】将Ubuntu16.04 中gedit在仅显示一个文件时显示文件名tab
查看>>
fstream 对象多次使用时注意clear
查看>>