Linux通过AIO进行异步读文件

下面列出源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <aio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>


static char *memBuffer;
static int sFileDesc;
static struct sigaction sOldSigAction;

static void MySigQuitHandler(int sig)
{
    printf("Signal Quit! The number is: %d\n", sig);
}

static void MyFileReadCompleteProcedure(int sig, siginfo_t *si, void *ucontext)
{
    printf("The file length is: %zu, and the content is: %s\n", strlen(memBuffer), memBuffer);
    int status = close(sFileDesc);
    if(status == 0)
        puts("File closed successfully!");
    else
        printf("The error code is: %d\n", status);

    free(memBuffer);

    // 还原原来的SIGUSR1信号行为
    if(sigaction(SIGUSR1, &sOldSigAction, NULL) == -1)
        puts("SIGUSR1 signal restore failed!");
}

int main(void)
{
    struct sigaction sigAction = { .sa_flags = SA_RESTART, .sa_handler = &MySigQuitHandler };

    sigemptyset(&sigAction.sa_mask);

    if (sigaction(SIGQUIT, &sigAction, NULL) == -1)
    {
        puts("Signal failed!");
        return -1;
    }

    sigAction.sa_sigaction = &MyFileReadCompleteProcedure;
    if(sigaction(SIGUSR1, &sigAction, &sOldSigAction) == -1)
    {
        puts("Signal failed!");
        return -1;
    }

    const char *filePath = "myfile.txt";

    const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
    sFileDesc = open(filePath, O_RDONLY, mode);
    if(sFileDesc == -1)
    {
        printf("The file: %s cannot be opened!\n", filePath);
        return -1;
    }

    const long fileLength = lseek(sFileDesc, 0, SEEK_END);
    lseek(sFileDesc, 0, SEEK_SET);

    memBuffer = malloc(fileLength + 1);
    memBuffer[fileLength] = '\0';

    struct aiocb aioBuffer;
    aioBuffer.aio_fildes = sFileDesc;
    aioBuffer.aio_offset = 0;
    aioBuffer.aio_buf = memBuffer;
    aioBuffer.aio_nbytes = fileLength;
    aioBuffer.aio_reqprio = 0;
    aioBuffer.aio_sigevent = (struct sigevent){.sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGUSR1, .sigev_value.sival_ptr = memBuffer };

    aio_read(&aioBuffer);

    getchar();

    return 0;
}

其中,上述代码实现中采用 SIGUSR1 信号进行捕获文件读完成事件,当然,这里也可以用 SIGIO 信号。

另外,在编译链接时必须添加 -lrt 命令选项,因为rt库才包含了系统底层的API。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值