多進程之間的互斥信號量的實現(Linux和windows跨平臺)

        最近工做中遇到了一些關於文件讀取權限的問題。當一個程序中對一個固定名稱的文件作了讀寫的操做的時候,外界經過併發式的調用這個應用的時候,可能存在多個進程同時去操做這個文件,這個時候可能會形成調用失敗的問題。因此這個時候,在操做文件以前就應該給該操做加鎖,遵循先來先行,後來等待的效果,從而保證各個進程都可以正常的執行本身的功能。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()

這個只是最近工做中的一點收穫,也算是本身的知識庫也多了一點東西。對象

相關文章
相關標籤/搜索