进程间同步互斥浅浅探索、没有函数用法

进程同步通信

Proc

#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include <sys/sem.h>
int semctl(int sem_id, int sem_num, int command, ...);
int semget(key_t key, int num_sems, int sem_flags);
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);

// linux 共享内存+信号量 https://blog.csdn.net/fengweibo112/article/details/119611439
// semget https://www.cnblogs.com/52php/p/5851570.html

class Monitor
{
public:
	Monitor(std::string path1, std::string path2);
	~Monitor();

public:
    void enq();
    void ouq();
    void fun();

public:
    int keySem;
    int keyShm;
    int semNum;

    void* shm;
};

Monitor(std::string path1, std::string path2)
{
    keySem = ftok(path1.c_str(), 1);
    keyShm = ftok(path2.c_str(), 2);

    semId = semget(keySem, 0, 0);
    shmId = shmget(keyShm, 0, 0);

    if (-1 == semId)
    {
        semId = semget(keySem, semNum, IPC_CREAT | IPC_EXCL | 0666)
    }    
    if (-1 == shmId)
    {
        semId = shmget(keySem, Size, ?);
    }
}


但是这种方法虽然没有明说被遗弃,但是很多人已经默认过时不再使用 // <sys/sem.h>
当前更多使用的是<semaphore.h>

简单说一下各个函数

  1. ftok(pahtname, num)

    根据pathnamenum来生成一个key,用于semget\shmget\mesget

  2. semget()

    获取信号量

  3. shmget()

    获取共享内存

  4. mesget()

    获取消息

管程、进程间通信(管道,共享内存,消息)

管程

首先明白,管程需要自己写,本质是将pv操作和共享内存进行了封装(javaGolang好像有现成的包)

管程封装成为一种结构或者软件包?

  1. 必要性

    • 不进行封装的情况下,pv操作和共享内存独立,操作的时候经常会出现匹配问题
  2. 模型

    管程分为两种模型

    1. MESA模型
    2. HOARE模型
  3. 不得不使用管程

    Sure. Suppose you want to take an action if you can acquire the lock, but if some other object already owns it, you don’t want to block for longer than a certain time:

    bool gotMonitor = false;
    
    try
    {
        Monitor.TryEnter(monitor, 500, ref gotMonitor);
        if (gotMonitor)
        {
            // Okay, we're in the lock. We can do something useful now.
        }
        else
        {
            // Timed out - do something else
        }
    }
    finally
    {
        if (gotMonitor)
        {
            Monitor.Exit(monitor);
        }
    }
    

    大佬说:

    • 管程不是一个独立的程序,而是一个概念,像golang中的wait_groupjava中的synchronized都是,但是 c++好像没有类似的库,但是可以带着mutexcondition_variable自己实现类似管程的功能

    • 管程不算是一个独立的程序,而相当于一个Model,不应该说有一个管程,而应该是使用管程 Monitor

    • 可以理解为,假设 C++有这么一个类库,不同的程序使用这一个相同的 Minitor类来操作互斥资源

命名管道(FIFO)

与管道的区别:提供了一个路径名与之关联,以FIFO文件的形式存储于文件系统中,能够实现任何两个进程之间通信。 而匿名管道对于文件系统是不可见的,它仅限于在父子进程之间的通信

#pragma once
#include "stdafx.h"
#include <windows.h>

#define BUF_SIZE 4096

class Monitor
{
public:
    Monitor();
    ~Monitor();

    void PV(int flag);
public:
    HANDLE hMapFile;    // 新创建的文件映射对象的句柄
    LPVOID lpBase;      // 内存映射视图
    HANDLE hmutex;      // 互斥锁

    char szBuffer[100];
};

#include "Monitor.h"

Monitor::Monitor()
{
    hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, NULL, L"ShareMemory");
    if (!hMapFile)
    {
        hMapFile = CreateFileMapping(
            INVALID_HANDLE_VALUE,       // 物理文件句柄
            NULL,                       // 默认安全级别
            PAGE_READWRITE,             // 可读可写
            0,                          // 高位文件大小
            BUF_SIZE,                   // 地位文件大小
            L"ShareMemory"              // 共享内存名称
        );
    }

    lpBase = MapViewOfFile(
        hMapFile,            // 共享内存的句柄
        FILE_MAP_ALL_ACCESS, // 可读写许可
        0,
        0,
        BUF_SIZE
    );

    hmutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, TEXT("MutexTest"));

    if (hmutex == NULL)
    {
        hmutex = CreateMutex(NULL, false, TEXT("MutexTest"));
    }
}

Monitor::~Monitor()
{
    if (hmutex != NULL)
    {
        CloseHandle(hmutex);
    }

    UnmapViewOfFile(lpBase);
    CloseHandle(hMapFile);
}

void Monitor::PV(int flag)
{
    WaitForSingleObject(hmutex, INFINITE);

    if (flag == 1)
        strcpy((char*)lpBase, szBuffer);
    else if (flag == 2)
        strcpy(szBuffer, (char*)lpBase);

    ReleaseMutex(hmutex);
}

共享内存

命名管道中的示例,使用的就是共享内存,不再重复代码

Linux中的共享内存是shmget那一系列,在windows下无法使用,所以先不考虑,想用的时候可以直接搜,教程不少

消息

Linux中用的是mesgetwindows下无法使用,可以自己搜一下

示例代码中用到的函数

#include <sys/shm.h>

共享内存

  • LPVOID lpBase; // 内存映射视图

  • hMapFile = CreateFileMapping(); // 创建共享内存

  • lpBase = MapViewOfFile(); // 共享内存映射

  • 使用

    • strcpy(szBuffer, (char*)lpBase);
    • strcpy((char*)lpBase, szBuffer);
  • 释放

    • UnmapViewOfFile(lpBase);
    • CloseHandle(hMapFile);

mutex

  • HANDLE hmutex; // 互斥锁

  • 创建

    hmutex = CreateMutex(NULL, false, TEXT("MutexTest"));

  • 打开

    hmutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, TEXT("MutexTest"));

  • 关闭

    ReleaseMutex(hmutex);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值