[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;
}
相关推荐
代码对我眨眼睛2 分钟前
Ubuntu 系统 NVIDIA 显卡驱动自动化安装全流程
linux·ubuntu·自动化
xiong2learning2 分钟前
Linux虚拟机无法使用u盘的一种可能-- 重新下载open-vm-tools + open-vm-tools-desktop解决
linux
q***64974 分钟前
VS与SQL Sever(C语言操作数据库)
c语言·数据库·sql
LCG元5 分钟前
实战:一次完整的网站故障排查记录(从用户访问到数据库)
linux
xuyanqiangCode10 分钟前
Ubuntu二进制安装Apache Doris(2.1版本)
linux·ubuntu·apache
Yue丶越12 分钟前
【Python】基础语法入门(四)
linux·开发语言·python
木童66216 分钟前
Nginx 深度解析:反向代理与负载均衡、后端Tomcat
linux·运维·nginx
赖small强42 分钟前
【Linux 网络基础】网络通信中的组播与广播:基础概念、原理、抓包与应用
linux·网络·broadcast·组播·广播·multicast
陌路201 小时前
Linux是如何收发网络包的?
linux·网络
带鱼吃猫2 小时前
Linux系统:策略模式实现自定义日志功能
linux·c++