AIO Asynchronous I/O with a callback function——寻找最佳方式
AIO Asynchronous I/O with a callback function -- looking for best way
我正在尝试学习 POSIX
异步 I/O。下面是我对别人的插图代码所做的编辑。我想了解一些事情。
首先,我在关闭 int
read_complete
的末端附近有一个忙等待循环。这是一个“可接受的”(安全的,无论如何,......)替代 aio_error()
的 return 值的替代方法吗?另外,我在考虑作为忙等待循环的替代方法,有一种方法可以让主线程休眠并让回调函数发送某种信号将其唤醒。但我不知道该怎么做,如果可以的话。
最后,我想弄清楚如何将更多信息输入回调函数 i_am_done
。例如,假设我想将输入数据推送到一个缓冲区中,或者将其拆分到缓冲区之间,以便主线程稍后使用,如果我有多个读取操作,则每次调用的缓冲区可能不同。我怎样才能让 i_am_done
知道缓冲区是什么?
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <aio.h>
//#include <bits/stdc++.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
const int BUFSIZE = 1024;
int read_complete = 0;
void i_am_done(sigval_t sigval)
{
struct aiocb *req;
req = (struct aiocb *)sigval.sival_ptr; //Pay attention here.
/*Check again if the asynchrony is complete?*/
if (aio_error(req) == 0)
{
read_complete = 1;
}
close(req->aio_fildes);
}
int main(void)
{
struct aiocb my_aiocb;
struct timeval t0, t1;
int fd = open("file.txt", O_RDONLY);
if (fd < 0)
perror("open");
bzero((char *)&my_aiocb, sizeof(my_aiocb));
my_aiocb.aio_buf = malloc(BUFSIZE);
if (!my_aiocb.aio_buf)
perror("my_aiocb.aio_buf");
my_aiocb.aio_fildes = fd;
my_aiocb.aio_nbytes = BUFSIZE;
my_aiocb.aio_offset = 0;
//Fill in callback information
/*
Using SIGEV_THREAD to request a thread callback function as a notification method
*/
my_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD;
my_aiocb.aio_sigevent.sigev_notify_function = i_am_done;
my_aiocb.aio_sigevent.sigev_notify_attributes = NULL;
my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb;
int ret = aio_read(&my_aiocb);
if (ret < 0)
perror("aio_read");
//The calling process continues to execute
while (read_complete != 1) {}
printf("main thread %s\n", (char*)my_aiocb.aio_buf);
return 0;
}
回答问题 #2,只需定义一个数据结构,您可以在其中存储所需的附加数据,然后将 sival_ptr
设置为该结构。例如:
struct my_data {
struct aiocb cb;
// For demonstration's sake:
int foo;
char *bar;
size_t quux;
}
// ...
struct my_data data;
data.cb.aio_sigevent.sigev_value.sival_ptr = &data;
// Setup the rest of the struct and execute the read.
在回调中,您现在可以访问 my_data 结构。
我正在尝试学习 POSIX
异步 I/O。下面是我对别人的插图代码所做的编辑。我想了解一些事情。
首先,我在关闭 int
read_complete
的末端附近有一个忙等待循环。这是一个“可接受的”(安全的,无论如何,......)替代 aio_error()
的 return 值的替代方法吗?另外,我在考虑作为忙等待循环的替代方法,有一种方法可以让主线程休眠并让回调函数发送某种信号将其唤醒。但我不知道该怎么做,如果可以的话。
最后,我想弄清楚如何将更多信息输入回调函数 i_am_done
。例如,假设我想将输入数据推送到一个缓冲区中,或者将其拆分到缓冲区之间,以便主线程稍后使用,如果我有多个读取操作,则每次调用的缓冲区可能不同。我怎样才能让 i_am_done
知道缓冲区是什么?
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <aio.h>
//#include <bits/stdc++.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
const int BUFSIZE = 1024;
int read_complete = 0;
void i_am_done(sigval_t sigval)
{
struct aiocb *req;
req = (struct aiocb *)sigval.sival_ptr; //Pay attention here.
/*Check again if the asynchrony is complete?*/
if (aio_error(req) == 0)
{
read_complete = 1;
}
close(req->aio_fildes);
}
int main(void)
{
struct aiocb my_aiocb;
struct timeval t0, t1;
int fd = open("file.txt", O_RDONLY);
if (fd < 0)
perror("open");
bzero((char *)&my_aiocb, sizeof(my_aiocb));
my_aiocb.aio_buf = malloc(BUFSIZE);
if (!my_aiocb.aio_buf)
perror("my_aiocb.aio_buf");
my_aiocb.aio_fildes = fd;
my_aiocb.aio_nbytes = BUFSIZE;
my_aiocb.aio_offset = 0;
//Fill in callback information
/*
Using SIGEV_THREAD to request a thread callback function as a notification method
*/
my_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD;
my_aiocb.aio_sigevent.sigev_notify_function = i_am_done;
my_aiocb.aio_sigevent.sigev_notify_attributes = NULL;
my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb;
int ret = aio_read(&my_aiocb);
if (ret < 0)
perror("aio_read");
//The calling process continues to execute
while (read_complete != 1) {}
printf("main thread %s\n", (char*)my_aiocb.aio_buf);
return 0;
}
回答问题 #2,只需定义一个数据结构,您可以在其中存储所需的附加数据,然后将 sival_ptr
设置为该结构。例如:
struct my_data {
struct aiocb cb;
// For demonstration's sake:
int foo;
char *bar;
size_t quux;
}
// ...
struct my_data data;
data.cb.aio_sigevent.sigev_value.sival_ptr = &data;
// Setup the rest of the struct and execute the read.
在回调中,您现在可以访问 my_data 结构。