多線程之間實現互斥操作方式很多種,臨界區(Critical Section),互斥量(Mutex),信號量(Semaphore),事件(Event)等方式
其中臨界區,互斥量,信號量算是嚴格意義的實現互斥操作的,事件應該說算是一種線程間的通信機制來保證互斥
在多線程中,可以直接將這些變量定義為全局的,然後在不同的線程中使用,那麼多進程環境就不行了。
多進程如果要實現多共享資源的互斥操作,只能使用互斥量(Mutex)
Mutex分為命名和匿名互斥量,進程間只能使用命名方式。
windows下面的操作函數為:CreateMutex,WaitForSingleObject,ReleaseMutex,CloseHandle
linux下面的操作函數為:sem_open,sem_wait,sem_post,sem_close(關閉當前進程中的互斥量句柄,內核中仍然存在),sem_unlink(從內核中移除互斥量)
下面封裝了一個跨平台實現多進程互斥操作的類,我自己測試過,可以拿來使用:
ProcessMutex.h文件:
1 #ifndef __PROCESS_MUTEX_H__ 2 #define __PROCESS_MUTEX_H__ 3 4 #ifdef WIN32 5 #include <Windows.h> 6 #endif 7 8 #ifdef linux 9 #include <unistd.h> 10 #include <semaphore.h> 11 #include <stdio.h> 12 #include <fcntl.h> 13 #include <signal.h> 14 #include <string.h> 15 #include <memory.h> 16 #endif 17 18 class CProcessMutex 19 { 20 public: 21 /* 默認創建匿名的互斥 */ 22 CProcessMutex(const char* name = NULL); 23 ~CProcessMutex(); 24 25 bool Lock(); 26 bool UnLock(); 27 28 private: 29 30 #ifdef WIN32 31 void* m_pMutex; 32 #endif 33 34 #ifdef linux 35 sem_t* m_pSem; 36 #endif 37 char m_cMutexName[30]; 38 }; 39 40 #endif
ProcessMutex.cpp文件:
1 #include "ProcessMutex.h" 2 3 #ifdef WIN32 4 5 CProcessMutex::CProcessMutex(const char* name) 6 { 7 memset(m_cMutexName, 0 ,sizeof(m_cMutexName)); 8 int min = strlen(name)>(sizeof(m_cMutexName)-1)?(sizeof(m_cMutexName)-1):strlen(name); 9 strncpy(m_cMutexName, name, min); 10 m_pMutex = CreateMutex(NULL, false, m_cMutexName); 11 } 12 13 CProcessMutex::~CProcessMutex() 14 { 15 CloseHandle(m_pMutex); 16 } 17 18 bool CProcessMutex::Lock() 19 { 20 //互斥鎖創建失敗 21 if (NULL == m_pMutex) 22 { 23 return false; 24 } 25 26 DWORD nRet = WaitForSingleObject(m_pMutex, INFINITE); 27 if (nRet != WAIT_OBJECT_0) 28 { 29 return false; 30 } 31 32 return true; 33 } 34 35 bool CProcessMutex::UnLock() 36 { 37 return ReleaseMutex(m_pMutex); 38 } 39 40 #endif 41 42 #ifdef linux 43 44 CProcessMutex::CProcessMutex(const char* name) 45 { 46 memset(m_cMutexName, 0 ,sizeof(m_cMutexName)); 47 int min = strlen(name)>(sizeof(m_cMutexName)-1)?(sizeof(m_cMutexName)-1):strlen(name); 48 strncpy(m_cMutexName, name, min); 49 m_pSem = sem_open(name, O_RDWR | O_CREAT, 0644, 1); 50 } 51 52 CProcessMutex::~CProcessMutex() 53 { 54 int ret = sem_close(m_pSem); 55 if (0 != ret) 56 { 57 printf("sem_close error %d\n", ret); 58 } 59 sem_unlink(m_cMutexName); 60 } 61 62 bool CProcessMutex::Lock() 63 { 64 int ret = sem_wait(m_pSem); 65 if (ret != 0) 66 { 67 return false; 68 } 69 return true; 70 } 71 72 bool CProcessMutex::UnLock() 73 { 74 int ret = sem_post(m_pSem); 75 if (ret != 0) 76 { 77 return false; 78 } 79 return true; 80 } 81 82 #endif