通常,共享内存是使用映射到进程地址空间的部分On-Disk文件实现的.每当在共享区域上发生内存访问时,文件系统就会在磁盘上写入更改,这是一个很大的开销.
通常,调用fopen()返回传递给mmap()的文件描述符以创建文件的内存映射.shm_open显然,工作方式相同.它返回它甚至可以与普通的文件操作(例如,使用的文件描述符ftruncate,ftell,fseek...等).我们指定一个字符串作为参数shm_open但不像fopen(),它不是可见文件系统上的真实文件的名称(已安装的HDD,闪存驱动器,SSD等).完全不相关的进程可以使用相同的字符串名称将相同的区域映射到其地址空间.
那么,传递给shm_open什么shm_open创建/打开的字符串参数是什么?它是一个临时文件系统(/ tmp)上的文件,最终被许多进程用来创建共享区域(嗯,我认为它必须是某种文件,因为它返回文件描述符)?或者它是由内核支持的某种神秘且隐藏的文件系统?
人们说shm_open比较快,fopen因为没有磁盘操作,所以我建议的理论是内核使用一个不可见的基于RAM的文件系统来实现共享内存shm_open!
我正在阅读 GNU C 手册的摘录:
\n\n\n\n\n您可以使用逗号运算符来分隔两个(表面上相关的)表达式。
\n
稍后在描述中:
\n\n\n\n\n如果要在函数参数中使用逗号运算符,则需要在其两侧加上括号。\xe2\x80\x99s 因为函数参数列表中的逗号具有不同的含义:它们分隔参数。
\n
到现在为止,一切都还好。奇怪的部分是:
\n\n\n\n\n\n
foo (x, (y=47, x), z);是一个只有三个参数的函数调用。(第二个参数是(y=47, x)。)
问题是:参数如何压入堆栈,如何从函数内部访问它?
\n我写了以下C代码.但是在运行时它给了我不正确的变量值sb,所以我尝试用GDB调试它,我发现int division E(vdes->addr, bs)(#define E(X,Y) X/Y)的汇编代码是完全不可理解的,似乎没有做正确的事情.
文件:main.c
typedef struct virtual_file_descriptor
{
int dfb;
int addr;
} vfd;
vfd vdes;
if(!strcmp(argv[1], "write")){
vdes.dfb = atoi(argv[2]);
vdes.addr = atoi(argv[3]);
vwrite(&vdes, inbuffer, atoi(argv[4]));
}
Run Code Online (Sandbox Code Playgroud)
文件:vwrite.c
#define E(X,Y) X/Y
#define bs sizeof(D_Record)*MAX_BLOCK_ENTRIES
int vwrite(vfd *vdes, char *buffer, int size){
if(!vdes)
return -1;
int sb, nb, offset;
sb = E(vdes->addr, bs) + 1; // i did 140/280 => wrong result
offset = vdes->addr - (sb - 1) * bs;
printf("size=%d …Run Code Online (Sandbox Code Playgroud)