最近工做中遇到了一些關於文件讀取權限的問題。當一個程序中對一個固定名稱的文件作了讀寫的操做的時候,外界經過併發式的調用這個應用的時候,可能存在多個進程同時去操做這個文件,這個時候可能會形成調用失敗的問題。因此這個時候,在操做文件以前就應該給該操做加鎖,遵循先來先行,後來等待的效果,從而保證各個進程都可以正常的執行本身的功能。linux
對於單個進程來講,進程內部的多個線程之間實現互斥的功能就方法不少,臨界區(CriticalSection),互斥量(Mutex),信號量(Semaphore),事件(Event)等方式。其中臨界區、互斥量、信號量都是嚴格意義上的實現互斥操做的,事件應該算是一種線程間的通訊實現的互斥。windows
在多線程中,能夠直接將這些函數定義爲全局變量直接去使用,可是對於進程而言,則不能這樣作。多線程
多進程若是想實現互斥操做,那麼只能使用互斥量(Mutex)的方式。併發
Mutex分爲匿名和命名互斥量,進程之間只能經過命名互斥實現。由於進程間回去檢測同一個命名互斥對象在當前系統是否已經存在,若是存在,則須要等待,直到該互斥信息解除。若是匿名互斥,那麼根本無法去檢測到目標信息是哪個,是否存在。函數
windows下互斥操做包含幾個函數:CreateMutex,WaitForSingleObject,ReleaseMutex,CloseHandlepost
Linux下互斥包含幾個函數:sem_open,sem_wait,sem_post,sem_close(關閉當前進程中的互斥量句柄,內核中依舊存在),sem_unlink(從內核中移除互斥量)線程
下面封裝了一個跨平臺的實現多進程操做的類。code
//ProcessMutex.h文件: #ifndef __PROCESS_MUTEX_H__ #define __PROCESS_MUTEX_H__ #ifdef WIN32 #include <Windows.h> #endif #ifdef linux #include <unistd.h> #include <semaphore.h> #include <stdio.h> #include <fcntl.h> #include <signal.h> #include <string.h> #include <memory.h> #endif class CProcessMutex { public: /* 默認建立匿名的互斥 */ CProcessMutex(const char* name = NULL); ~CProcessMutex(); bool Lock(); bool UnLock(); private: #ifdef WIN32 void* m_pMutex; #endif #ifdef linux set_t* m_pSem; #ednif char m_cMutexName[30]; }; #endif
//ProcessMutex.cpp文件: #include "ProcessMutex.h" #ifdef WIN32 CProcessMutex::CProcessMutex(const char* name) { memset(m_cMutexName, 0 ,sizeof(m_cMutexName)); int min = strlen(name)>(sizeof(m_cMutexName)-1)?(sizeof(m_cMutexName)-1):strlen(name); strncpy(m_cMutexName, name, min); m_pMutex = CreateMutex(NULL, false, m_cMutexName); } CProcessMutex::~CProcessMutex() { CloseHandle(m_pMutex); } bool CProcessMutex::Lock() { //互斥鎖建立失敗 if (NULL == m_pMutex) { return false; } DWORD nRet = WaitForSingleObject(m_pMutex, INFINITE); if (nRet != WAIT_OBJECT_0) { return false; } return true; } bool CProcessMutex::UnLock() { return ReleaseMutex(m_pMutex); } #endif #ifdef linux CProcessMutex::CProcessMutex(const char* name) { memset(m_cMutexName, 0 ,sizeof(m_cMutexName)); int min = strlen(name)>(sizeof(m_cMutexName)-1)?(sizeof(m_cMutexName)-1):strlen(name); strncpy(m_cMutexName, name, min); m_pSem = sem_open(name, O_CREAT, 0644, 1); } CProcessMutex::~CProcessMutex() { int ret = sem_close(m_pSem); if (0 != ret) { printf("sem_close error %d\n", ret); } sem_unlink(m_cMutexName); } bool CProcessMutex::Lock() { int ret = sem_wait(m_pSem); if (ret != 0) { return false; } return true; } bool CProcessMutex::UnLock() { int ret = sem_post(m_pSem); if (ret != 0) { return false; } return true; } #endif
//使用方式 CProcessMutex pMutex("MutexName"); pMutex.Lock(); //互斥內容或者函數 pMutex.UnLock()
這個只是最近工做中的一點收穫,也算是本身的知識庫也多了一點東西。對象