这个程序中的posix_memalign是什么意思?

What is the meaning of the posix_memalign in this program?

我读过一个程序,它使用 DIRECT_IO 来插入一个寄存器(prof 结构)。我怀疑我是否在此处正确使用 posix_memalign 。我知道分配的内存块必须对齐才能使用 DIRECT_IO 方法。

我的程序是(正在运行,但请让我知道任何建议):

#define _GNU_SOURCE /* for O_DIRECT */

#include <stdio.h>
#include <sys/types.h>  /* required by open() */
#include <unistd.h>     /* open(), write() */
#include <fcntl.h>      /* open() and fcntl() */
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <malloc.h>

#define PAGE_SIZE 4096
#define LENGTH  50

typedef struct {
    int nusp;
    char first_name[LENGTH];
    char last_name[LENGTH];
    char department[LENGTH];
    int year_of_begin;
} prof;

int disk_open() {
    int flag;
    int ret;

    flag = O_CREAT | O_RDWR | O_DIRECT;

    if ((ret = open("test.header", flag, S_IRUSR | S_IWUSR)) < 0) {
        printf("was impossible to create the file");
        return -1;
    }
    return ret;
}

int main() {
    int cmd;
    prof d;
    int arq;
    uint8_t *buf, *loc;
    size_t bufsize;

    do {
        printf("Digite:\n");
        printf("****\n(1) insert\n(2) see register\n(3) leave\n****\n");
        scanf("%d", &cmd);
        switch (cmd) {
            case 1:
                printf("ID: ");
                scanf("%d", &(d.nusp));

                printf("NAME: ");
                scanf("%s", (d.first_name));

                printf("LASTNAME: ");
                scanf("%s", (d.last_name));

                printf("DEPARTAMENT: ");
                scanf("%s", (d.department));

                printf("YEAR: ");
                scanf("%d", &(d.year_of_begin));

                bufsize = sizeof (int) +
                        sizeof (d.first_name) +
                        sizeof (d.last_name) +
                        sizeof (d.department) +
                        sizeof (int);
                printf("bufsize = %d\n", bufsize);
                //buf = (uint8_t*) malloc(bufsize);
                if(posix_memalign((void**)&buf, PAGE_SIZE, bufsize)) {
                    printf("allocation failed\n");
                }

                loc = buf;

                memcpy(loc, &(d.nusp), sizeof (int));
                loc += sizeof (int);

                memcpy(loc, d.first_name, sizeof (d.first_name));
                loc += sizeof (d.first_name);

                memcpy(loc, d.last_name, sizeof (d.first_name));
                loc += sizeof (d.last_name);

                memcpy(loc, d.department, sizeof (d.department));
                loc += sizeof (d.department);

                memcpy(loc, &(d.year_of_begin), sizeof (int));
                loc += sizeof (int);

                arq = disk_open();
                printf("bytes written: %d\n", write(arq, buf, PAGE_SIZE));

                free(buf);

                close(arq);
                break;

            case 2:
                arq = disk_open();

                bufsize = sizeof (int) +
                        sizeof (d.first_name) +
                        sizeof (d.last_name) +
                        sizeof (d.department) +
                        sizeof (int);
                //buf = (uint8_t*) malloc(bufsize);
                 posix_memalign((void**)&buf, PAGE_SIZE, bufsize);

                printf("read %d bytes\n", read(arq, buf, PAGE_SIZE));

                memcpy(&(d.nusp), buf, sizeof (int));
                buf += sizeof (int);

                memcpy(d.first_name, buf, sizeof (d.first_name));
                buf += sizeof (d.first_name);

                memcpy(d.last_name, buf, sizeof (d.last_name));
                buf += sizeof (d.last_name);

                memcpy(d.department, buf, sizeof (d.department));
                buf += sizeof (d.department);

                memcpy(&(d.year_of_begin), buf, sizeof (int));
                buf += sizeof (int);

                printf("ID: %d\n", d.nusp);
                printf("NAME: %s\n", d.first_name);
                printf("LAST NAME: %s\n", d.last_name);
                printf("DEPARTAMENT: %s\n", d.department);
                printf("YEAR: %d\n", d.year_of_begin);
                printf("\n");

                close(arq);
                break;

            default:
                printf("Leaving....");
                break;
        }
    } while (cmd != 3);
    return 0;
}

所以,我的问题是: 在 posix_memalign((void**)&buf, PAGE_SIZE, bufsize);,我是否在 4096 字节的块内存(即我的页面大小)中分配了 158 字节,这意味着我浪费了 3938 字节?发生这种情况是因为我必须 write/read 对齐的块内存,在这种情况下是 4096(2 的幂),对吗?

如果我的 PAGE_SIZE 等于 bufsize 会发生什么(考虑 bufsize 和 PAGE_SIZE 在这种情况下的大小等于 4096 字节)?这是否意味着我不会在内存和磁盘中浪费字节?

如果我想在Windows中使用DIRECT_IO,可以吗?如果是,我必须使用哪个 library/function 来分配对齐的块内存?

您将返回保证与 PAGE_SIZE 对齐的内存块;而已。不要假设最后有 3938 字节的 space 未使用 - 智能分配器可以轻松地为您提供页面对齐内存块中的第一个条目,并保留其余的 158 字节分配。

您只使用了 PAGE_SIZE 磁盘块的 158 字节,浪费了磁盘上的一大块 space,实际上您的写入实际上是将未定义的数据放入该块的磁盘 - 从 158 到 4096 的所有内容从未分配给您,您应该尝试读取或写入该内存。

如果 PAGE_SIZE == bufsize,那么您不会浪费任何磁盘 space。

another question,它解释了如何获得与 O_DIRECT 标志类似的行为。