Linux 共享内存

本文介绍了共享内存常用函数,如shmget、shmat、shmdt、shmctl,说明了各函数功能、使用头文件和参数含义,并给出示例。还给出了使用共享内存的实例,包括创建工程、各程序功能及代码实现,以及Makefile和头文件内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

共享内存常用函数介绍:

int shmget(key_t key,size_t size,int shmflg);

函数说明:得到一个共享内存标识符shmid

使用头文件:#include <sys/ipc.h> #include <sys/shm.h>

参数:

key:共享内存段名字,可通过fork函数生成,使用如:ftok("./", 66);

size:共享内存大小,以字节为单位;

shmflg:

IPC_CREAT: 如果共享内存不存在,则创建一个共享内存,否则打开操作;

IPC_EXCL:只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。

例如:

key = ftok("/mnt/hgfs/Homework",87);

shmid = shmget(key, sizeof(struct shared_use_st), IPC_CREAT|0666);

 

void *shmat(int shmid,const void *shmaddr,int shmflg);

函数说明:映射共享内存,将共享内存区对象映射到调用进程的地址空间,返回的是一个指针,指向共享内存第一个字节

使用头文件:#include <sys/types.h> #include <sys/shm.h>

参数:

shmid:共享内存标识符

shmaddr: 指定共享内存出现在进程内存地址的什么位置,通常指定为NULL,让内核自己选择一个合适的地址位置

shmflg:通常为0

例如:

char *shm_buf = NULL; //虚拟地址

shm_buf = shmat(shmid, (void *)0, 0);

 

int shmdt(const void *shmaddr);

函数说明:将共享内存与当前进程脱离

使用头文件:#include <sys/types.h> #include <sys/shm.h>

参数:shmddr 连接共享内存的起始地址

例如:

if(-1 == shmdt(shm_buf))

 

int shmctl(int shmid,int cmd, struct shmid_ds* buf);

函数说明:控制共享内存块

使用头文件:#include <sys/types.h> #Include <sys/shm.h>

参数:

shmid:共享内存标识符

cmd:

IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构赋值到buf所指向的buf中

IPC_SET:改变共享内存的状态,把buf所指向的shmid_ds结构中的uid、gid、mode赋值到共享内存的shmid_ds结构内

IPC_RMID:删除这块共享内存

buf:共享内存管理结构体,一般为NULLs

例如:

if(-1 == shmctl(shmid, IPC_RMID, NULL))

 

使用共享内存实例:

功能:linux下创建工程,至少包括三个以上目录,可以实现单独编译,全编译,程序1从文件输入指令流,并将程序指令流传输到程序2, 程序2在屏幕上显示指令的操作结果,程序3可以控制程序1,2的暂停和退出。

说明:

1.txt中存放字符串命令;

write.c负责读取1.txt中的命令并向共享内存中写入数据;

read.c负责读取共享内存中的数据并向共享内存中写入自身设备号;

control.c负责读取共享内存中所有的信息,并实现对read.c和write.c状态的控制

D.h:存放共享内存数据结构体

 

write.c

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include "D.h"

 

int main(void)

{

int fd = -1;

char buf[128]={0}; //用来存储从文件获取的命令字符串

int shmid;

char *shm_buf = NULL; //虚拟地址

struct shared_use_st *shared = NULL;

key_t key;

 

//从文件中读取指令,存放在buf中 pwd存放在1.txt中

fd = open("/mnt/hgfs/Homework/1.txt",O_RDWR);

if(-1 == fd)

{

perror("open failed!");

exit(1);

}

read(fd,buf,127);//获取指令并存放在buf中

printf("Get_Command:%s",buf);

//创建一个共享内存,返回一个id

key = ftok("/mnt/hgfs/Homework",87);

shmid = shmget(key, sizeof(struct shared_use_st), IPC_CREAT|0666);

if(-1 == shmid)

{

perror("shmget failed!");

exit(2);

}

//映射共享内存,得到虚拟地址

shm_buf = shmat(shmid, (void *)0, 0);

if((void *)-1 == shm_buf)

{

perror("shmat failed!");

exit(3);

}

//写共享内存

shared = (struct shared_use_st *)shm_buf;

strcpy(shared->text,buf);

shared->id1 = getpid();

printf("share_data:%s",shared->text);

printf("Write_id1:%d\n",shared->id1);

 

//解除映射

if(-1 == shmdt(shm_buf))

{

perror("shmdt failed!");

exit(4);

}

//销毁共享内存

/* if(-1 == shmctl(shmid, IPC_RMID, NULL))

{

perror("shmctl failed!");

exit(5);

}

printf("destory success!\n");

*/

close(fd);

while(1);

 

return 0;

}

 

read.c

 

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include "D.h"

 

int main(void)

{

int shmid;

char *shm_buf = NULL;

struct shared_use_st *shared;

key_t key;

pid_t pid;

 

//生成一个key

key = ftok("/mnt/hgfs/Homework",87);

//获取共享内存,返回一个id

shmid = shmget(key, sizeof(struct shared_use_st), IPC_CREAT|0666);

if(-1 == shmid)

{

perror("shmget failed!");

exit(6);

}

 

//映射共享内存,得到虚拟地址

shm_buf = shmat(shmid, (void *)0, 0);

if((void *)-1 == shm_buf)

{

perror("shmat failed!");

exit(7);

}

//读共享内存

pid = getpid();

shared = (struct shared_use_st *)shm_buf;

printf("Share_Read_Data:%s",shared->text);

printf("Write_id1:%d\n",shared->id1);

shared->id2 = pid;

printf("Read_id2:%d\n",pid);

 

printf("The Path in the next:\n");

system(shared->text);//通过system函数来执行text中存放的字符串命令

 

//解除映射

if(-1 == shmdt(shm_buf))

{

perror("shmdt failed!");

exit(8);

}

while(1);

return 0;

}

 

control.c

 

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include "D.h"

 

int main(void)

{

int shmid;

char *shm_buf = NULL;

struct shared_use_st *shared;//申请结构体指针变量

key_t key;

pid_t pid;

int Read_id,Write_id;

int num;

char buffer1[200],buffer2[200],buffer3[200],buffer4[200],buffer5[200],buffer6[200];//进行格式转换存储

 

//生成一个key

key = ftok("/mnt/hgfs/Homework",87);

//获取共享内存,返回一个id

shmid = shmget(key, sizeof(struct shared_use_st), IPC_CREAT);

if(-1 == shmid)

{

perror("shmget failed!");

exit(6);

}

//映射共享内存,得到虚拟地址

shm_buf = shmat(shmid, (void *)0, 0);

if((void *)-1 == shm_buf)

{

perror("shmat failed!");

exit(7);

}

//读共享内存

pid = getpid();

 

shared = (struct shared_use_st *)shm_buf;

printf("Share_Read_Data:%s",shared->text);

printf("The Path in the next:\n");

system(shared->text);//通过system函数来执行text中存放的字符串命令

printf("Write_id1:%d\n",shared->id1);

printf("Read_id2:%d\n",shared->id2);

printf("Own_id3:%d\n",pid);

Write_id = shared->id1;

Read_id = shared->id2;

 

//解除映射

if(-1 == shmdt(shm_buf))

{

perror("shmdt failed!");

exit(8);

}

/****************操作进程*******************/

 

//字符转换

sprintf(buffer1,"kill -STOP %d",Write_id);

sprintf(buffer2,"kill -STOP %d",Read_id);

sprintf(buffer3,"kill -CONT %d",Write_id);

sprintf(buffer4,"kill -CONT %d",Read_id);

sprintf(buffer5,"kill -KILL %d",Write_id);

sprintf(buffer6,"kill -KILL %d",Read_id);

 

printf("please input a num!\n");

scanf("%d",&num);

switch(num)

{

case 1:

system(buffer1);

printf("stop Write success!\n");

break;

case 2:

system(buffer2);

printf("stop Read success!\n");

break;

case 3:

system(buffer3);

printf("cont Write success!\n");

break;

case 4:

system(buffer4);

printf("cont Read success!\n");

break;

case 5:

system(buffer5);

printf("kill Write success!\n");

break;

case 6:

system (buffer6);

printf("kill Read success!\n");

break;

default:

printf("input a error number!\n");

}

return 0;

}

 

Makefile:

#! /bin/bash

 

all:mk1 mk2 mk3

$(MAKE) -C ./Read

$(MAKE) -C ./Write

$(MAKE) -C ./Control

 

mk1:

$(MAKE) -C ./Write

mk2:

$(MAKE) -C ./Read

mk3:

$(MAKE) -C ./Control

clean:

rm -rf test

rm -rf ./Read/*.o

rm -rf ./Write/*.o

rm -rf ./Control/*.o

 

D.h

#pragma once //在头文件中加入这条指令能够被编译一次

 

#define TEXT_SZ 1024

struct shared_use_st

{

int id1;//存放程序1id

int id2;//存放程序2id

char text[TEXT_SZ]; //记录写入和读取的文本

};

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值