多线程之间实现互斥操作方式很多种,临界区(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文件:
#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
sem_t* m_pSem;
#endif
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_RDWR | 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