动态 版块 发帖 消息 我的
小绿叶技术博客
小绿叶技术博客
小绿叶技术Lv150   
c 进程通信-共享内存创建与读取(c语言)     



# 创建共享内存, w.c



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>         // 共享内存函数
#include <string.h>
#include <signal.h>

#include <errno.h>

struct Msg {
    int flag;                // flag 的数值 0为读,1为写
    char content[104];
};
// 声明结构体 Msg 里面的 变量定义类型, 下次给变量赋值,直接引用当前结构体赋值,不用定义类型

int shmid;
void *pshm;

void Handle(int s) {
// 定义一个无类型函数,属性是 s 由其他函数传值过来,

    if (s == 2)
// 判断s 的值 绝对等于2 

    {
        shmdt(pshm);
// 将共享内存地址抽离

        shmctl(shmid, IPC_RMID, 0);
// 删除共享内存
        exit(0);
    }
}

// 共享内存 4 函数定义;
// shmget()  创建共享内存,返回内存 shmid; 参数: 1.起名 2.内存地址大小 3.为0 是读取内存。创建内存要 填写权限 。
// 共享内存参数: IPC_CREAT 区别 IPC_EXCL  都是不存在就创建共享内存,区别 creat 是存在共享就打开, excl是存在就产生错误   
// shmat()   返回内存空间地址并挂载, 1. 挂载到内存上的id  2.填0/null 自动找位置,3.标志位
// shmdt     删除挂载 参数:shmat 返回值。 成功返回0,失败返回-1
// shmctrl   删除内存 

int gongxiang() {
    signal(2, Handle);                                 // signal.h是C标准函数库中的信号处理部分 ,按ctrl+c键退出时会处理这个消息,进行共享内存卸载、删除操作,最后exit(0)退出程序
    key_t key = ftok(".", 0x1);                        // ftok 生成key数值,参数1 路径,参数2数字 1-255 之间,数字会加在key数值的前面     
    printf(" \n key 获取的数值:%x \n", key);            // x 以16进制打印。 d 十进制; o 八进制        
    shmid = shmget(key, 100, IPC_CREAT | IPC_EXCL | 0666); // key 为 ftok 的返回值 ; 字节大小 100 ; shmflg:文件权限
                                                       // 创建共享内存,成功返回共享内存的ID,出错返回-1
                                                       // IPC_CREAT | IPC_EXCL则可以创建一个新的,唯一的共享内存,如果共享内存已存在,返回一个错误。*/
 
    pshm = shmat(shmid, 0, 0);                         //  shmat 附加好的内存地址,出错返回-1
                                                       //  共享内存标识符 ID 号; 映射到地址; 0 可读写, SHM_RDONLY 只读
 
    if (*(int *)pshm == -1) {                          // 查看挂接是否成功如果出错返回-1,报错
        printf("shmat error!\n");
        exit(0);
    }

    memset(pshm, 0, 100);                              //初始化: 替换 0 的位置 为 100
    struct Msg *msg = (struct Msg *)pshm;
    msg->flag = 1;                                     // 定义msg 结构体中的变量 flag 成员的数值 为1 是写入

    while (1) {
        if (msg->flag == 1) {                          //当为1时写消息,此时读文件中不能操作此共享内存
            printf("请输入内容至共享内存:");

            scanf("%s", msg->content);
            msg->flag = 0;                             //当写消息后flag置为0,让读文件开始执行读操作,此时写文件不能进行写操作
        }
        else {
            sleep(1);
        }
    }
    return 0;
}

int main(){
    gongxiang();
}




// ftok 说明:https://wenku.baidu.com/view/eac76f2e5b1b6bd97f192279168884868762b804.html?_wkts_=1667455715129&bdQuery=c+ftok+%E5%87%BD%E6%95%B0
// 参考案例:https://blog.csdn.net/arv002/article/details/109830080
// 共享内存函数说明:https://blog.csdn.net/weixin_35710880/article/details/117180126






# 读取共享内存



//read.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h> 


// 共享内存 4 函数定义;
// shmget()  创建共享内存,返回内存 shmid; 参数: 1.起名 2.内存地址大小 3.为0 是读取内存。创建内存要 填写权限 。
// 共享内存参数: IPC_CREAT 区别 IPC_EXCL  都是不存在就创建共享内存,区别 creat 是存在共享就打开, excl是存在就产生错误   
// shmat()   返回内存空间地址并挂载, 1. 挂载到内存上的id  2.填0/null 自动找位置,3.标志位
// shmdt     删除挂载 参数:shmat 返回值。 成功返回0,失败返回-1
// shmctrl   删除内存 


struct Msg {
	int flag;
	char content[104];
};                                              // 定义结构体,下次引用不用定义变量类型
int main() {
 
	key_t key = ftok(".", 2);
	int shmid = shmget(key, 0, 0);              // 参数3 为0 是读取共享内存
 
	void *pshm = shmat(shmid, 0, 0);            //挂接操作,成功返回指向共享存储段的指针,出错返回-1
 
	if (*(int *)pshm == -1) {                   //查看挂接是否成功如果出错返回-1,报错
		printf("shmat error!\n");
		exit(0);
	}
 
	struct Msg * msg = (struct Msg *)pshm;

	while (1) {
		if (msg->flag == 0) {                   //当为0时读消息,此时写文件中不能操作此共享内存
			printf("从共享内存收到 : %s\n", msg->content);
			msg->flag = 1;
		}
		else {
			sleep(1);
		}
	}
 
	return 0;
}













 33  已被阅读了354次  楼主 2022-11-04 11:23:27
回复列表

回复:c 进程通信-共享内存创建与读取(c语言)

guest
登录之后更精彩~
Powered by HadSky 7.7.16
© 2015-2023 PuYueTian
您的IP:8.219.134.200,2023-02-01 15:13:29,Processed in 0.00836 second(s).
Powered by HadSky
小绿叶技术博客