歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux通過AIO進行異步讀文件

Linux通過AIO進行異步讀文件

日期:2017/3/1 9:20:10   编辑:Linux編程

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。

Copyright © Linux教程網 All Rights Reserved