Простой пример для aio_write()

Я ищу простой пример для функции POSIX aio_write.

Что я пробовал до сих пор

Следующее не так важно. Просто перейдите к ответу

Код ниже создает файл, но ничего в него не записывает. aio_error возвращает 22 (= quota exceeded, но на диске достаточно места и прав доступа r/w).

#include <aio.h>
#include <stdio.h>


char CONTENT[] = "asdf;";
const int LENGTH = 5;

struct aiocb createIoRequest(int fd,  
                            off_t offset, 
                            volatile void * content, 
                            size_t length){
    struct aiocb ret; // <-- not initialized. Will lead to an error ( see answer) 
    {
        ret.aio_fildes = fd;
        ret.aio_offset = offset;
        ret.aio_buf = content;
        ret.aio_nbytes = length;            
    }
    return ret;
}


int main(){

    FILE * file = fopen("outfile.txt","w");
    int fd = fileno(file);
    {    
        struct aiocb op  = createIoRequest(fd,0,CONTENT,LENGTH);        

        // schedule write
        // for valgrind mem leak output see comments from answer in
        //   https://stackoverflow.com/questions/4248720/aio-h-aio-read-and-write-memory-leak
        int ret = aio_write(&op);
        printf("aio_write 1: %d\n",ret);

        // wait until everything is done
        {
            const struct aiocb * aiolist[1];
            aiolist[0] = &op;

            int ret = aio_suspend(aiolist,1,NULL);
            printf("aio_suspend: %d\n",ret);

            // report possible errors
            {
                ret = aio_error(&op);
                printf("errno 1: %d\n",ret);
            }
        }
    }
    fclose(file);


    return 0;
}

person DarkTrick    schedule 11.02.2020    source источник
comment
настоятельно рекомендуем прочитать (aio_write)[software.intel.com/en-us/, который отвечает на ваш вопрос/запрос для примера   -  person user3629249    schedule 11.02.2020
comment
OT: относительно: FILE * file = fopen("outfile.txt","w"); При вызове fopen() всегда проверяйте (!=NULL) возвращаемое значение, чтобы убедиться, что операция прошла успешно. Подобные соображения существуют для всех библиотечных функций C.   -  person user3629249    schedule 11.02.2020


Ответы (1)


Проверка кода с помощью отчетов valgrind Conditional jump or move depends on uninitialised value(s)

Проблема с вашим кодом

aiocb не инициализирован.

Примеры

Приведенные ниже примеры не содержат проверок «успех» (например, file != NULL и т. д.). Это ради читабельности. В продуктивном коде вы должны проверять возвращаемые значения.

Пример1

Программа ниже записала asdf; в outfile.txt. Структура aiocb инициализируется внутри createIoRequest()

#include <aio.h>
#include <stdio.h>


char CONTENT[] = "asdf;";
const int LENGTH = 5;

struct aiocb createIoRequest(int fd,  
                            off_t offset, 
                            volatile void * content, 
                            size_t length){
    // create and initialize the aiocb structure.
    // If we don't init to 0, we have undefined behavior.
    // E.g. through sigevent op.aio_sigevent there could be 
    //      a callback function being set, that the program
    //      tries to call - which will then fail.
    struct aiocb ret = {0};
    {
        ret.aio_fildes = fd;
        ret.aio_offset = offset;
        ret.aio_buf = content;
        ret.aio_nbytes = length;            
    }
    return ret;
}


int main(){

    FILE * file = fopen("outfile.txt","w");
    int fd = fileno(file);
    {    
        struct aiocb op  = createIoRequest(fd,0,CONTENT,LENGTH);        

        // schedule write
        // for valgrind mem leak output see comments from answer in
        //   https://stackoverflow.com/questions/4248720/aio-h-aio-read-and-write-memory-leak
        int ret = aio_write(&op);
        printf("aio_write 1: %d\n",ret);

        // wait until everything is done
        {
            const struct aiocb * aiolist[1];
            aiolist[0] = &op;

            int ret = aio_suspend(aiolist,1,NULL);
            printf("aio_suspend: %d\n",ret);

            // report possible errors
            {
                ret = aio_error(&op);
                printf("errno 1: %d\n",ret);
            }
        }
    }
    fclose(file);


    return 0;
}

Пример2

Программа ниже просто расширяет программу выше, чтобы иметь две асинхронные записи в файл.

#include <aio.h>
#include <stdio.h>


char CONTENT[] = "asdf;";
const int LENGTH = 5;

struct aiocb createIoRequest(int fd,  
                            off_t offset, 
                            volatile void * content, 
                            size_t length){
    // create and initialize the aiocb structure.
    // If we don't init to 0, we have undefined behavior.
    // E.g. through sigevent op.aio_sigevent there could be 
    //      a callback function being set, that the program
    //      tries to call - which will then fail.
    struct aiocb ret = {0};
    {
        ret.aio_fildes = fd;
        ret.aio_offset = offset;
        ret.aio_buf = content;
        ret.aio_nbytes = length;            
    }
    return ret;
}


int main(){

    FILE * file = fopen("outfile.txt","w");
    int fd = fileno(file);
    {    
        struct aiocb op  = createIoRequest(fd,0,CONTENT,LENGTH);
        struct aiocb op2 = createIoRequest(fd,LENGTH,CONTENT,LENGTH);

        // schedule write
        // for valgrind mem leak output see comments from answer in
        //   https://stackoverflow.com/questions/4248720/aio-h-aio-read-and-write-memory-leak
        int ret = aio_write(&op);
        printf("aio_write 1: %d\n",ret);
        ret = aio_write(&op2);
        printf("aio_write 2: %d\n",ret);        

        // wait until everything is done
        {
            const int OPs = 2;
            const struct aiocb * aiolist[OPs];
            aiolist[0] = &op;
            aiolist[1] = &op2;

            int ret = aio_suspend(aiolist,OPs,NULL);
            printf("aio_suspend: %d\n",ret);

            // report possible errors
            {
                ret = aio_error(&op);
                printf("errno 1: %d\n",ret);
                ret = aio_error(&op2);
                printf("errno 2: %d\n",ret);
                // error codes can be checked in <errno.h>
            }
        }
    }
    fclose(file);


    return 0;
}
person DarkTrick    schedule 11.02.2020