最近工作中遇到了一些关于文件读取权限的问题。当一个程序中对一个固定名称的文件做了读写的操作的时候,外界通过并发式的调用这个应用的时候,可能存在多个进程同时去操作这个文件,这个时候可能会造成调用失败的问题。所以这个时候,在操作文件之前就应该给该操作加锁,遵循先来先行,后来等待的效果,从而保证各个进程都能够正常的执行自己的功能。

对于单个进程来说,进程内部的多个线程之间实现互斥的功能就方法很多,临界区(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跨平台)的更多相关文章

  1. 多进程之间的互斥信号量实现(Linux和windows跨平台)

    多线程之间实现互斥操作方式很多种,临界区(Critical Section),互斥量(Mutex),信号量(Semaphore),事件(Event)等方式 其中临界区,互斥量,信号量算是严格意义的实现 ...

  2. 分享一实战性开源MVC框架<Linux、Windows跨平台开发so easy>

    一.引子   开源地址 https://github.com/564064202/Moon.Mvc 欢迎加入开发 .NET Core微软还在发力,但作为商用还有一段距离,很多开发库尚不能用于.NET ...

  3. Linux 驱动——Button驱动6(mutex、NBLOCK、O_NONBLOCK)互斥信号量、阻塞、非阻塞

    button_drv.c驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include <linux/f ...

  4. Linux多进程之间的文件锁

    之前对于文件的操作通常在一个进程中完成,最近需要在两个进程中对同一个文件进行操作.故想到了文件锁. Linux下可以使用flock()函数对文件进行加锁解锁等操作.简单介绍下flock()函数: 表头 ...

  5. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  6. ucos之互斥信号量及优先级反转

    在ucos常使用共享资源来作为任务之间的通信方式,其中有:消息队列,信号量,邮箱,事件.信号量中又分二值信号,多值信号,互斥信号.这次主要讲二值信号与互斥信号之间区别和使用. 首先了解一下ucos的任 ...

  7. Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型

    Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: ​ ​ ​ 每个对象都对应于一个可称为" 互斥锁&qu ...

  8. 设置共享,实现Linux和Windows之间的共享

    设置共享,实现Linux和Windows之间的共享 前提: 安装虚拟机.可以参考:在Windows上安装虚拟机详细图文教程 安装Linux.可以参考:在VMware Workstation里的Linu ...

  9. Linux和windows之间通过scp复制文件

    Windows是不支持ssh协议的 需要安装WinSSHD 安装以及设置过程如下: BvSshServer(原名winsshd)官方下载页在这里:https://www.bitvise.com/dow ...

随机推荐

  1. 定义Java类实现字节流转字符流

    package com.buaa.comparable; import java.io.BufferedReader;import java.io.File;import java.io.FileIn ...

  2. navicat for oracle 导入xlsx文件提示无法打开xlsx文件

    navicat for oracle 导入xlsx文件提示:无法打开xlsx文件 导入环境: navicat for oracle wps状态的xlsx文件 处理: 将wps状态的xlsx文件,打开方 ...

  3. Django:总结setting中的配置

    一.Django setting配置说明 二.setting配置一览 一.Django setting配置说明 1.基础 DJANGO_SETTING_MODULE环境变量:让settings模块被包 ...

  4. Linux 下DNS详解

    配置之前先了解一下bind DNS服务器软件:BIND是一种开源的DNS(Domain Name System)协议的实现,包含对域名的查询和响应所需的所有软件.它是互联网上最广泛使用的一种DNS服务 ...

  5. linux-2.6.38 IIC驱动框架分析

    在linux-2.6内核中,IIC的驱动程序可以大概分为三部分: (1)IIC核心代码:/drivers/i2c/i2c-core.c IIC核心提供了IIC总线驱动和设备驱动的注册.注销方法和IIC ...

  6. idou老师教你学Istio 27:解读Mixer Report流程

    1.概述 Mixer是Istio的核心组件,提供了遥测数据收集的功能,能够实时采集服务的请求状态等信息,以达到监控服务状态目的. 1.1 核心功能 •前置检查(Check):某服务接收并响应外部请求前 ...

  7. ubuntu---记录.opencv多版本管理与切换

    首先当然准备两个不同版本opencv (比如2..9和3.1.0) cmake-gui 设置 CMAKE_INSTALL_PREFIX 安装路径:/usr/local/opencv2 安装路径 :/u ...

  8. Reverse数组以及大O表达式

    这篇主要是对数组实现一个倒排序(比如数组1.2.3,最后输出3.2.1),当然实现这个功能是非常easy的事,但是这里需要引入另外一个很重要的概念-----如何计算一个算法的时间复杂度并学会用大O表达 ...

  9. 解决 分布式事务中HRESULT:0x8004D025 错误

    最近在开发分布式事务的过程中,碰到 该伙伴事务管理器已经禁止了它对远程/网络事务的支持. (异常来自 HRESULT:0x8004D025)的错误. 后来检查到,原来是数据库服务器的MSDTC 没有设 ...

  10. gdb设置条件断点

    b +行号 if i==9:设置条件断点 finish:执行到当前函数返回处(退出函数) bt:打印栈帧关系