Linux进程通信——共享内存(中)

简介: Linux进程通信——共享内存(中)

shmat

第一个参数是想和哪一个共享内存关联,第二个参数是想把这个共享内存映射到地址空间的哪个地方(不常用),第三个权限是读写权限(一般设置为0)。

返回值是将映射到虚拟地址空间的起始地址位置返回。(等价于C语言的malloc)

失败返回-1。

void* attachshm(int shmid)
{
    void* p = shmat(shmid, nullptr, 0);
    if((long long)p == -1L)//因为linux系统是64位,一个地址是8个字节,所以要变成8个字节大小的数据类型做对比
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
        exit(4);
    }
    return p;
}

这里就代表挂接成功了,这个共享内存挂接了一个进程。

那么如何去关联呢?

shmdt

其实就是调用去卸载当前进程共享内存的地虚拟地址空间,参数就是shmat的返回值。

返回值成功是0,错误是-1.

void detachshm(void* p)
{
    if(shmdt(p) == -1)
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
    }
}

然后完善一下另一个文件中的代码:

这一份不需要他释放掉共享内存。

这里让server多休息一会。

通信

然后来完善通信的一下代码:

#ifndef _COMM_HPP_
#define _COMM_HPP_
#include<iostream>
#include<cassert>
#include<cstring>
#include<cerrno>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<cstdlib>
#include<unistd.h>
#define PATHNAME "."//ftok的第一个参数,是一个合法路径
#define PROJ_IO 0X666//ftok的第二个参数
#define MAX_SIZE 4096//共享内存的大小
key_t getkey()
{
    key_t k = ftok(PATHNAME, PROJ_IO);
    if(k < 0)
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
        exit(1);
    }
    return k;
}
int getshmhelper(key_t k, int flags)
{
    int shmid = shmget(k, MAX_SIZE, flags);
    if(shmid < 0)
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
        exit(2);
    }
    return shmid;
}
int getshm(key_t k)//获取共享内存
{
    return getshmhelper(k, IPC_CREAT);//没有就创建,有就获取
}
int createshm(key_t k)//创建共享内存
{
    return getshmhelper(k, IPC_CREAT | IPC_EXCL | 0600);//没有创建,有就报错,这里创建内存需要给对应的权限
}
void delshm(int shmid)
{
    if(shmctl(shmid, IPC_RMID, nullptr) == -1)
    {
        std::cerr << errno << ":" << strerror(shmid) << std::endl;
        exit(3);
    }
}
void* attachshm(int shmid)
{
    void* p = shmat(shmid, nullptr, 0);
    if((long long)p == -1L)//因为linux系统是64位,一个地址是8个字节,所以要变成8个字节大小的数据类型做对比
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
        exit(4);
    }
    return p;
}
void detachshm(void* p)
{
    if(shmdt(p) == -1)
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
    }
}
#endif
#include"shm.hpp"
int main()
{
    key_t k = getkey();
    printf("0x%x\n",k);
    int shmid = getshm(k);//接收共享内存
    printf("shmid : %d\n", shmid);
    char* p = (char*)attachshm(shmid);//关联
    printf("attach sucess, address p: %p\n",p);
    //使用
    const char* str = "hello server, 我是另一个进程,我在和你通信";
    pid_t id = getpid();
    int count = 0;
    while(true)
    {
        sleep(1);
        snprintf(p, MAX_SIZE, "%S[pid:%d][消息编号:%d]", str, id, count++);
    }
    detachshm(p);//去关联
    return 0;
}
#include"shm.hpp"
int main()
{
    key_t k = getkey();
    printf("0x%x\n",k);
    int shmid = createshm(k);//创建共享内存
    printf("shmid : %d\n", shmid);
    char* p = (char*)attachshm(shmid);//关联
    printf("attach sucess, address p: %p\n",p);
    //使用
    while(true)
    {
        printf("client say: %s\n",p);
        sleep(1);
    }
    detachshm(p);//去关联
    sleep(10);
    delshm(shmid);//删除共享内存
    return 0;
}

相关文章
|
10天前
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第7天】麒麟系统mate-indicators进程占用内存过高问题解决
65 2
|
10天前
|
存储 缓存 监控
Linux中内存和性能问题
【10月更文挑战第5天】
25 4
|
8天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
【10月更文挑战第9天】本文将深入浅出地介绍Linux系统中的进程管理机制,包括进程的概念、状态、调度以及如何在Linux环境下进行进程控制。我们将通过直观的语言和生动的比喻,让读者轻松掌握这一核心概念。文章不仅适合初学者构建基础,也能帮助有经验的用户加深对进程管理的理解。
12 1
|
9天前
|
算法 Linux
Linux中内存问题
【10月更文挑战第6天】
11 2
|
10天前
|
存储 缓存 固态存储
|
13天前
|
网络协议 Linux 网络性能优化
Linux C/C++之TCP / UDP通信
这篇文章详细介绍了Linux下C/C++语言实现TCP和UDP通信的方法,包括网络基础、通信模型、编程示例以及TCP和UDP的优缺点比较。
21 0
Linux C/C++之TCP / UDP通信
|
13天前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
16 0
Linux c/c++之IPC进程间通信
|
13天前
|
Linux C++
Linux c/c++进程间通信(1)
这篇文章介绍了Linux下C/C++进程间通信的几种方式,包括普通文件、文件映射虚拟内存、管道通信(FIFO),并提供了示例代码和标准输入输出设备的应用。
15 0
Linux c/c++进程间通信(1)
|
12天前
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第5天】麒麟系统mate-indicators进程占用内存过高问题解决
57 0
|
13天前
|
Linux C++
Linux c/c++进程之僵尸进程和守护进程
这篇文章介绍了Linux系统中僵尸进程和守护进程的概念、产生原因、解决方法以及如何创建守护进程。
15 0