共享内存
相比于前三个IPC方式,共享内存有什么不同?
我们可以假设两个人要进行交流,管道和FIFO就好像两人中间有一个水管,一方往里面放,另一方就只能拿;消息队列就好像一个人往箱子里面放纸条,另一个人从箱子里拿出纸条,读取完后再把纸条放回去(消息读完后不会消失,不同于管道);而共享内存就像两人中间有一张桌子,一个人往桌子上写东西,另一个人可以直接看到它写的(桌子对于两个人来说是共用的)。
由名字可知,两个进程可以挂载同一个内存空间,这个内存空间是共享的。
相关函数:
#include
//创建或获取一个共享内存:成功返回共享内存ID,失败返回-1
int shmget(key_t key, size_t size, int flag);
//连接共享内存到当前进程的地址空间:成功返回指向共享内存的指针,失败返回-1
void *shmat(int shm_id, const void *addr, int flag);
//断开与共享内存的连接:成功返回0,失败返回-1
int shmdt(void *addr);
//控制共享内存的相关信息:成功返回0,失败返回-1
int shmctl(int shm_id, int cmd, struct shmid_ds *buf);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
这个参数Key之间我是直接初始化为一个32位的整数,现在我们用一下其他方法,顺便学习一下一个函数——ftok函数。
#include
#include
key_t ftok(const char *pathname, int proj_id);
- 1
- 2
- 3
- 4
参数:
1.函数的第一个参数是一个路径名,通常是一个存在的文件路径,待会的代码示例中会传入".",这意味着 ftok 函数会使用当前进程的工作目录(即程序运行时所在的目录)作为路径来生成键值,我们只需要知道怎么使用就行了。
2.第二个参数proj_id,它用于进一步区分同一路径下不同对象(如消息队列、信号量、共享内存)的键值。在使用ftok函数时,传入的proj_id值应当是一个非零的整数。简单理解就是这个数字可以被视为一个简单的标识符,用于区分同一路径下不同的对象。
运用函数小demo:
write:
#include
#include
#include
#include
#include
#include
int main()
{
int shmid;
char *shmaddr;
key_t key;
key=ftok(".",1);//获取键值
shmid=shmget(key,1024*4,IPC_CREAT|0666);//创建一个共享内存,权限为可读可写,大小为4兆
if(shmid==-1)//创建/获取共享内存失败
{
printf("shmget failed\n");
exit(-1);
}
shmaddr=shmat(shmid,0,0);//挂载共享内存,获取地址
strcpy(shmaddr,"hello!\n");//将字符串复制到共享内存里
sleep(5);/眠五秒
shmdt(shmaddr);//取消挂载/卸载共享内存
shmctl(shmid,IPC_RMID,0);//删除共享内存
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
注意:
1.创建共享内存时,空间大小必须以兆为单位,即1024字节,shmget函数的第二个参数一般传入IPC_CREAT(创建),还需要|上创建的权限(0666表示可读可写,0777表示可读可写可执行)。
2.挂载共享内存shmat的第二和第三个参数通常写0即可,第二个参数写0表示让Linux内核为我们自动安排共享内存,第三个表示挂载/映射的共享内存为可读可写。
3.删除共享内存的第三个参数通常写0,表示不接收删除共享内存的信息等。
read:
#include
#include
#include
#include
#include
- 1
- 2
- 3
- 4
评论记录:
回复评论: