多进程之间的互斥信号量的实现(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()

这个只是最近工做中的一点收获,也算是本身的知识库也多了一点东西。对象

相关文章
相关标签/搜索