標籤:一點 控制代碼 function 不能 section 固定 意義 meta critical
最近工作中遇到了一些關於檔案讀取許可權的問題。當一個程式中對一個固定名稱的檔案做了讀寫的操作的時候,外界通過並髮式的調用這個應用的時候,可能存在多個進程同時去操作這個檔案,這個時候可能會造成調用失敗的問題。所以這個時候,在操作檔案之前就應該給該操作加鎖,遵循先來先行,後來等待的效果,從而保證各個進程都能夠正常的執行自己的功能。
對於單個進程來說,進程內部的多個線程之間實現互斥的功能就方法很多,臨界區(CriticalSection),互斥量(Mutex),訊號量(Semaphore),事件(Event)等方式。其中臨界區、互斥量、訊號量都是嚴格意義上的實現互斥操作的,事件應該算是一種線程間的通訊實現的互斥。
在多線程中,可以直接將這些函數定義為全域變數直接去使用,但是對於進程而言,則不能這樣做。
多進程如果想實現互斥操作,那麼只能使用互斥量(Mutex)的方式。
Mutex分為匿名和命名互斥量,進程之間只能通過命名互斥實現。因為進程間回去檢測同一個命名互斥對象在當前系統是否已經存在,如果存在,則需要等待,直到該互斥資訊解除。如果匿名互斥,那麼根本沒法去檢測到目標資訊是哪一個,是否存在。
windows下互斥操作包含幾個函數:CreateMutex,WaitForSingleObject,ReleaseMutex,CloseHandle
Linux下互斥包含幾個函數:sem_open,sem_wait,sem_post,sem_close(關閉當前進程中的互斥量控制代碼,核心中依舊存在),sem_unlink(從核心中移除互斥量)
下面封裝了一個跨平台的實現多進程操作的類。
//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()
這個只是最近工作中的一點收穫,也算是自己的知識庫也多了一點東西。
多進程之間的互斥訊號量的實現(Linux和windows跨平台)