[linux] linux c实现共享内存读写操作

IPC_PRIVATE

IPC_PRIVATE 是用于创建新的 System V IPC(Inter-Process Communication,进程间通信)对象的特殊键值。在使用 System V 共享内存、消息队列或信号量时,IPC_PRIVATE 可以作为 key 参数传递给 shmgetmsggetsemget 函数,以创建一个新的 IPC 对象, IPC_PRIVATE可以替换为自己的唯一key

特点

  • 唯一性 :使用 IPC_PRIVATE 创建的 IPC 对象是唯一的,只有创建它的进程及其子进程能够访问。这是因为 IPC_PRIVATE 实际上并不是一个真正的键值,而是一个特殊标识符,指示内核为调用进程创建一个新的、唯一的 IPC 对象。
  • 进程间隔离 :由于 IPC_PRIVATE 创建的对象不依赖于一个全局可见的键值,其他进程无法通过键值访问该对象,除非它们是通过继承的方式(如 fork)获得的。

IPC_PRIVATE 例子

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>

#define SHM_SIZE 1024  // 共享内存大小

int main() {
    // 创建共享内存段
    int shm_id = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
    if (shm_id == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    // 附加共享内存段
    char *shm_ptr = (char *)shmat(shm_id, NULL, 0);
    if (shm_ptr == (char *)-1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 写入数据到共享内存
    strncpy(shm_ptr, "Hello, Shared Memory!", SHM_SIZE);

    // 创建子进程
    pid_t pid = fork();
    if (pid == 0) {
        // 子进程读取共享内存
        printf("Child process reads: %s\n", shm_ptr);

        // 分离共享内存段
        if (shmdt(shm_ptr) == -1) {
            perror("shmdt");
            exit(EXIT_FAILURE);
        }
        exit(0);
    } else if (pid > 0) {
        // 父进程等待子进程结束
        wait(NULL);

        // 分离共享内存段
        if (shmdt(shm_ptr) == -1) {
            perror("shmdt");
            exit(EXIT_FAILURE);
        }

        // 删除共享内存段
        if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
            perror("shmctl");
            exit(EXIT_FAILURE);
        }
    } else {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    return 0;
}

自定义Key举例

复制代码
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
#include <errno.h>
#include <stdio.h>
#include <sys/sem.h>

#define DENY_MAC_SHM_SIZE 18  // MAC地址长度为17个字符,加上一个终止符
#define SHM_MAC_INFO_KEY    (0x00260000)
char *g_deny_mac = NULL;
int shm_init(unsigned int key,int shm_id)
{
    //int shm_id = -1;
    void *shm = NULL;
    if(NULL != g_deny_mac) 
    {
        printf("share memory had already init\r\n");
        return 0;
    }
    else
    {
        shm_id = shmget((key_t)SHM_MAC_INFO_KEY,DENY_MAC_SHM_SIZE,IPC_CREAT|0666);
        if(shm_id == -1)
        {
            printf("shmget failed:%s\n",strerror(errno));
            return -1;
        }
        shm = shmat(shm_id,NULL,0);
        g_deny_mac = (char *)shm;
    }
    return 0;
}
int set_deny_mac(char *mac,int len)
{
    int ret = 0;
    void *deny_mac = NULL;
   
    deny_mac = g_deny_mac;
    
    if(mac != NULL)
    {
        
        memcpy(deny_mac,mac,len);
    }
    else
    {
        ret = -1;
    }

    return ret;
}
int get_deny_mac(char *mac, int len)
{
    int ret = -1;
    void *deny_mac = NULL;
    
    deny_mac = g_deny_mac;

    memcpy(mac,g_deny_mac,len);
    if(strlen(mac) == len)
    {
        ret = 0;
    }
    else
    {
        ret = -1;
    }
    
    return ret;
}
void shm_free(int shm_id)
{
    
    void *shm_ptr = shmat(shm_id, NULL, 0);
    if (shm_ptr == (void *)-1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }
    // 分离共享内存段
    if (shmdt(shm_ptr) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    // 删除共享内存段
    if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
        perror("shmctl");
        exit(EXIT_FAILURE);
    }

    return ;
}
int main()
{
    char mac[] = "xx:xx:xx:00:00:01";
    char buf[18] = {0};
    int shm_id;

    shm_init(SHM_MAC_INFO_KEY,shm_id);
    get_deny_mac(buf,sizeof(buf));
    printf("buf=%s mac=%s\n",buf,mac); 
    set_deny_mac(mac,18);
    get_deny_mac(buf,18);
    printf("buf=%s mac=%s\n",buf,mac); 
    shm_free(shm_id);
    
    return 0;
}
相关推荐
爱尔兰的楠小楠36 分钟前
Windows上使用WSL2创建Ubuntu系统,实现无缝高效开发的体验
linux·windows·ubuntu
Fluency-1143 分钟前
ubuntu中ssh连接root用户
linux·ubuntu·ssh
0wioiw01 小时前
Ubuntu(③vsftpd)
linux·服务器·ubuntu
Fr2ed0m2 小时前
卡尔曼滤波算法原理详解:核心公式、C 语言代码实现及电机控制 / 目标追踪应用
c语言·人工智能·算法
Yupureki2 小时前
从零开始的C++学习生活 20:数据结构与STL复习课(4.4w字全解析)
c语言·数据结构·c++·学习·visual studio·1024程序员节
一念&3 小时前
每日一个C语言知识:C 错误处理
c语言·开发语言·算法
cellurw3 小时前
Day75 RS-485 通信协议设计、串口编程与嵌入式系统部署实践
linux
奔跑吧邓邓子3 小时前
【C语言实战(66)】筑牢防线:C语言安全编码之输入与错误处理
c语言·安全·开发实战·错误处理·输入验证
雨落在了我的手上4 小时前
C语言入门(十三):操作符详解(1)
c语言
海棠蚀omo5 小时前
Linux基础I/O-打开新世界的大门:文件描述符的“分身术”与高级重定向
linux·操作系统