Linux系统调用函数shmget()、shmat(),标准C库函数ftok()(创建共享内存段,创建共享内存段的键,把共享内存段加入当前的进程的地址空间中)
前言
如果,想要深入的学习Linux系统调用中的shmget、shmat函数与标准C库中的ftok函数,还是需要去自己阅读Linux系统中的帮助文档。
具体输入命令:
man 2 shmget/shmat
man 3 ftok
即可查阅到完整的资料信息。
shmget 函数
shmget() 是一个Linux系统调用函数,
用于创建一个新的共享内存段(segment)或获取一个已存在的共享内存段。这个函数会返回一个整数类型的共享内存标识符(ID),用于在后续的系统调用中引用共享内存段。
函数原型:
//使用此函数,需导入此头文件
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
参数说明:
key_t key: 一个键值,用于唯一标识一个共享内存段。你可以使用IPC_PRIVATE常量创建一个私有共享内存段,或使用ftok()函数根据文件路径生成一个唯一的键值。size_t size: 共享内存段的大小,以字节为单位。当创建新的共享内存段时,需要指定大小。对于已存在的共享内存段,这个参数可以忽略(设置为0的意思)。int shmflg: 一个标志位集合,用于控制共享内存段的访问权限和创建行为。这个参数通常包括两部分:权限标志(类似文件权限,如0644)和操作标志。操作标志可以是IPC_CREAT(如果共享内存段不存在,则创建一个新的共享内存段,如果共享内存段存在的话,也是使用这个参数,只不过不创建而已)或IPC_EXCL(与IPC_CREAT一起使用,确保共享内存段是新创建的,如果已存在,则返回错误)。
返回值:
- 成功时,shmget() 返回一个非负整数,表示共享内存段的标识符(ID)。
- 失败时,返回-1,并设置相应的errno。
使用示例:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
int main()
{
key_t key = ftok("somefile", 65); // Generate a unique key based on file path
int shmid = shmget(key, 1024, 0666 | IPC_CREAT); // Create a new shared memory segment of 1024 bytes
if (shmid == -1)
{
perror("shmget"); // Print error message if shmget fails
return 1;
}
printf("Shared memory segment ID: %d\n", shmid);
return 0;
}
- 总之,shmget()是一个Linux系统调用函数,用于创建或获取共享内存段。它需要提供一个键值、共享内存段的大小和标志位作为参数。成功时,它会返回一个共享内存段的标识(ID),用于后续的共享内存操作。
ftok 函数
ftok() 是一个标准C库函数,用于生成System V IPC(Inter-Process Communication,进程间通信)对象(如信号量、消息队列和共享内存)的键(key)。它
通常用于为IPC对象创建唯一的键,以便在多个进程之间识别和共享该对象。
函数原型:
//使用此函数,需导入此头文件
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
参数说明:
const char *pathname: 一个以null结尾的字符串,表示文件系统中文件的路径。文件应该在调用ftok()时存在。在多个进程中生成相同的键时,需要使用相同的文件路径。int proj_id: 一个非零的整数,作为生成键的种子。在多个进程中生成相同的键时,需要使用相同的proj_id。
返回值:
- 成功时,ftok() 返回一个非零的键(key_t 类型)。
- 失败时,返回-1,并设置相应的 errno。
使用示例:
#include <sys/ipc.h>
#include <stdio.h>
int main()
{
const char *pathname = "/tmp/somefile"; // Path to an existing file
int proj_id = 65; // A non-zero integer
key_t key = ftok(pathname, proj_id);
if (key == -1)
{
perror("ftok"); // Print error message if ftok fails
return 1;
}
printf("Generated key: %ld\n", (long)key);
return 0;
}
- 总之,ftok() 是一个标准C库函数,用于为System V IPC对象生成键。它需要提供文件系统中文件的路径和一个非零整数作为参数。通过使用相同的文件路径和非零整数,可以在多个进程之间生成相同的键,以便共享IPC对象。
shmat 函数
shmat() 是一个Linux系统调用函数,
用于将一个共享内存段附加到当前进程的地址空间。这使得进程可以通过指针访问共享内存段中的数据。shmat() 函数通常在调用 shmget() 函数后使用,以便将获得的共享内存段附加到进程的地址空间。
函数原型:
//使用此函数,需导入此头文件
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数说明:
int shmid: 一个整数,表示共享内存段的标识符(ID)。这个值通常是通过调用 shmget() 函数获得的。const void *shmaddr: 一个指针,表示附加共享内存段的首选地址。通常将此参数设置为NULL,让系统自动选择一个合适的地址。int shmflg: 一个整数,表示附加共享内存段的标志。常用标志包括:- SHM_RDONLY: 以只读方式附加共享内存段。
- 0: 以读写方式附加共享内存段。
返回值:
- 成功时,shmat() 返回一个非空指针,表示共享内存段在当前进程地址空间的起始地址。
- 失败时,返回 (void *)-1,并设置相应的 errno。
使用示例:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
int main()
{
key_t key = ftok("somefile", 65); // Generate a unique key based on file path
int shmid = shmget(key, 1024, 0666 | IPC_CREAT); // Create a new shared memory segment of 1024 bytes
if (shmid == -1)
{
perror("shmget"); // Print error message if shmget fails
return 1;
}
char *shmaddr = (char *)shmat(shmid, NULL, 0); // Attach the shared memory segment to the process
if (shmaddr == (char *)-1)
{
perror("shmat"); // Print error message if shmat fails
return 1;
}
// Now you can read/write data in the shared memory segment using the shmaddr pointer
return 0;
}
- 总之,shmat() 是一个Linux系统调用函数,用于将共享内存段附加到当前进程的地址空间。它需要提供共享内存段的标识符、首选地址和标志作为参数。成功时,它会返回一个指向共享内存段起始地址的指针,用于后续的内存访问操作。
总结
这篇文章介绍了Linux系统调用中的shmget、shmat函数与标准C库中的ftok函数。如果大家想要了解更多的标准C库函数知识,Linux系统调用函数知识,大家请看这两篇文章:
最后的最后,如果你觉得我的这篇文章写的不错的话,请给我一个赞与收藏,关注我,我会继续给大家带来更多更优质的干货内容。