【问题标题】:Simple example for aio_write()aio_write() 的简单示例
【发布时间】:2020-02-11 04:19:43
【问题描述】:

我正在寻找POSIX aio_write 函数的简单示例。

到目前为止我尝试了什么

以下不是太重要。直接跳回答

下面的代码创建一个文件,但不向其中写入任何内容。 aio_error 返回22(=quota exceeded,但驱动器上有足够的空间和读写权限)。

#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;
}

【问题讨论】:

  • 强烈建议阅读 (aio_write)[software.intel.com/en-us/… 回答您的问题/请求的示例
  • OT: about: FILE * file = fopen("outfile.txt","w"); 调用 fopen() 时,始终检查 (!=NULL) 返回值以确保操作成功。所有 C 库函数都存在类似的考虑

标签: c asynchronous io posix aio


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 2014-09-18
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    相关资源
    最近更新 更多