0
点赞
收藏
分享

微信扫一扫

C++信号量与共享内存实现进程间通信

_铁马冰河_ 2023-07-28 阅读 76

关于信号量和共享内存的相关知识可参考下面链接:

进程间通信方式介绍_夜雨听萧瑟的博客-CSDN博客

C++ 创建共享内存_c共享内存_夜雨听萧瑟的博客-CSDN博客

 信号量SytemV与Posix信号量的介绍与用法_夜雨听萧瑟的博客-CSDN博客

直接上代码,代码如下:

#include <iostream>
#include <string>
#include <unistd.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <string.h>
#define SHARE_MEM_SIZE 2048
class Semaphore
{
private:
    union semVar
    {
        int val;
        struct semid_ds *buf;
        unsigned short *array;
    };

    int sem_id;
public:
    bool init(key_t key);
    bool wait();
    bool post();
    bool destroy();
};


bool Semaphore::init(key_t key)
{
    sem_id = semget(key,0,0640);
    if(-1 == sem_id)
    {
        if(2 == errno)
        {
            sem_id = semget(key,1,0640|IPC_CREAT);
            if(-1 == sem_id)
            {
                std::cout << "init 1 semget() error" << std::endl;
                return false;
            }else
            {
                union semVar semTmp;
                semTmp.val = 1;
                if(semctl(sem_id,0,SETVAL,semTmp) < 0)
                {
                     std::cout << "init 1 semctl() error" << std::endl;
                     return false;
                }else
                {
                    return true;
                }
            }
        }else
        {
            std::cout << "init 2 semget() error" << std::endl;
            return false;
        }
    }else
    {
        return true;
    }

}


bool Semaphore::wait(){
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = -1;
    sem_b.sem_flg = SEM_UNDO;
    if(-1 == semop(sem_id,&sem_b,1))
    {
        std::cout << "wait semop failed." << std::endl;
        return false;
    }
    return true;
}

bool Semaphore::post()
{
    struct sembuf sem_b;
    sem_b.sem_num = 0;
    sem_b.sem_op = 1;
    sem_b.sem_flg = SEM_UNDO;
    if(-1 == semop(sem_id,&sem_b,1))
    {
        std::cout << "post semop failed." << std::endl;
        return false;
    }
    return true;
}

bool Semaphore::destroy()
{
    if(semctl(sem_id,0,IPC_RMID) == -1)
    {
        std::cout << "destroy semctl failed." << std::endl;
        return false;
    }
    return true;
}

int main()
{
    Semaphore sem;
    //初始化信号灯
    if(false == sem.init(0x5000))
    {
        std::cout << "sem init failed." << std::endl;
        return -1;
    }
    std::cout << "sem init ok." << std::endl;

    
    int shmid = 0;  //内存标识符

    //创建共享内存
    shmid = shmget((key_t)0x5005,SHARE_MEM_SIZE,0640|IPC_CREAT);
    if(-1 == shmid)
    {
        std::cout << "create shareMem failed." << std::endl;
        return -1;
    }

    char* pMemSharedMem = 0;
    ///
    //等待信号灯挂出,等待成功后,将持有锁
    if(false == sem.wait())
    {
        std::cout << "sem wait failed." << std::endl;
        return -1;
    }
    std::cout << "sem wait ok." << std::endl;

    sleep(10);
    
    //将当前进程与共享内存shmid建立链接,shmat返回指定共享内存的映射地址
    pMemSharedMem = (char*)shmat(shmid,0,0);
    std::cout << "read context: " << pMemSharedMem << std::endl;


    std::string strContext = "hello world, "+ std::to_string(getpid());
    strncpy(pMemSharedMem,strContext.c_str(),strContext.length());
    std::cout << "write after: " << pMemSharedMem << std::endl;

    //shmat的反操作,将共享内存与当前进程分离
    shmdt(pMemSharedMem);
    
    //挂出信号灯
    if(false == sem.post())
    {
        std::cout << "sem post failed." << std::endl;
        return -1;
    }
    std::cout << "sem post ok." << std::endl;

    //销毁信号灯
    //if(false == sem.destroy())
    //{
    //    std::cout << "sem destroy failed." << std::endl;
    //    return -1;
    //}
    //std::cout << "sem destroy ok." << std::endl;

    return 0;
}

同时运行3个进程,运行结果如下:

 

举报

相关推荐

0 条评论