blog/docs/note/learn/linux-aio-异步io.md
王一之 460c6cdc87
All checks were successful
Release / deploy (push) Successful in 2m13s
acme协议
2024-03-30 00:33:36 +08:00

76 lines
2.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: linux aio 异步io
---
> linux 下的 aio 有 glibc 的和内核所提供的glibc 是使用的多线程的模式模拟的,另外一种是真正的内核异步通知了,
> 已经使用在了 nginx 上,前面看了一下 swoole 的实现,是类似与 glibc 那种多线程的模式。
> 不过两种方法都有一定的毛病,多线程模拟自然是有所效率损失,然而内核不能利用系统的缓存,只能以 O_DIRECT 方式做直接 IO所以看知乎上有一个
> **linux 下的异步 IOAIO是否已成熟** 的问题,不过那是 2014 年的事情了,不知道现在怎么样。
在此之前需要安装好 **libaio**
```bash
sudo apt install libaio-dev
```
## 函数
头文件:`#include <libaio.h>`
## 例子
> 一个一步读取文件内容的例子
```c
#include <stdio.h>
#include <fcntl.h>
#include <libaio.h>
#include <malloc.h>
#include <mhash.h>
#define MAX_EVENT 10
#define BUF_LEN 1024
void callback(io_context_t ctx, struct iocb *iocb, long res, long res2) {
printf("test call\n");
printf("%s\n", iocb->u.c.buf);
}
int main() {
int fd = open("/home/huanl/client.ovpn", O_RDONLY, 0);
io_context_t io_context;
struct iocb io, *p = &io;
struct io_event event[MAX_EVENT];
char *buf = malloc(BUF_LEN);
memset(buf, 0, BUF_LEN);
memset(&io_context, 0, sizeof(io_context));
if (io_setup(10, &io_context)) {
printf("io_setup error");
return 0;
}
if (fd < 0) {
printf("open file error");
return 0;
}
io_prep_pread(&io, fd, buf, BUF_LEN, 0);
io_set_callback(&io, callback);
if (io_submit(io_context, 1, &p) < 0) {
printf("io_submit error");
return 0;
}
int num = io_getevents(io_context, 1, MAX_EVENT, event, NULL);
for (int i = 0; i < num; i++) {
io_callback_t io_callback = event[i].data;
io_callback(io_context, event[i].obj, event[i].res, event[i].res2);
}
return 0;
}
```
## 参考
[https://jin-yang.github.io/post/linux-program-aio.html](https://jin-yang.github.io/post/linux-program-aio.html)