非同期 I/O  概説 Introduction to Asynchronous I/O AIO, I/O Multiplexing…
今日の目的 <ul><li>非同期 I/O とは何かを知る </li></ul><ul><li>非同期 I/O を使うと何がうれしいのかを知る </li></ul><ul><li>非同期 I/O を実現する手段(複数)を知る </li></ul>
アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></u...
アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></u...
ネットワークサーバのお仕事を考えてみる <ul><li>Web サーバとか </li></ul><ul><li>I/O (ネットワーク I/O 、ディスク I/O )に着目 </li></ul><ul><ul><li>リクエストを受ける(ネット...
一般的な I/O の特性 <ul><li>read(2)/write(2) </li></ul><ul><ul><li>いつでもデータが読める / 書けるとは限らない </li></ul></ul><ul><ul><li>準備ができるまで戻らな...
ネットワークサーバ ×I/O <ul><li>ネットワークサーバ </li></ul><ul><ul><li>ネットワーク I/O 、ディスク I/O を伴う </li></ul></ul><ul><li>I/O ブロッキング </li></u...
The C10K problem <ul><li>The C10K problem </li></ul><ul><ul><li>http://www.kegel.com/c10k.html </li></ul></ul><ul><ul><li>...
C10K - I/O 戦略 <ul><li>1スレッド:1クライアントで、ブロッキング I/O </li></ul><ul><ul><li>× 各スレッドでスタックを消費する </li></ul></ul><ul><ul><ul><li>NPT...
アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></u...
I/O モデルの整理 Synchronous Asynchronous Blocking Non-blocking read/write read/write (O_NONBLOCK) I/O multiplexing I/O 多重化 (sel...
I/O 多重化とは <ul><li>I/O 可能になった fd の集合を通知するしくみ </li></ul><ul><ul><li>通知後に、 read(2),write(2) を行う </li></ul></ul><ul><li>実装 </l...
AIO とは <ul><li>非同期に I/O を行うしくみ </li></ul><ul><ul><li>通知時にはすでに read や write が完了している </li></ul></ul><ul><ul><li>read の場合はバッフ...
I/O 多重化  vs AIO <ul><li>select(2) はブロックする  ※タイムアウトは指定可能 </li></ul><ul><li>通知後に read(2) が必要=コンテキストスイッチ </li></ul>
I/O 多重化  vs AIO <ul><li>ブロックしない=ほかの処理を行える </li></ul><ul><li>シグナルかコールバックが非同期に呼ばれる </li></ul><ul><li>通知時には既にバッファに入ってる </li><...
アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></u...
AIO の実装 –  Linux 2.6 <ul><li>POSIX AIO – POSIX 準拠 </li></ul><ul><ul><li>aio_read / aio_write, aio_error, aio_return, … </l...
AIO の実装 –  FreeBSD 6.2 <ul><li>POSIX AIO – POSIX 準拠 </li></ul><ul><ul><li>aio_read / aio_write, aio_error, aio_return, … <...
アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></u...
POSIX AIO –  スレッド通知 iocb->aio_fildes = … iocb->aio_buf  = … iocb->aio_nbytes = … iocb->aio_offset = … iocb->aio_sigevent.s...
POSIX AIO –  スレッド通知/注意点 <ul><li>スレッドセーフ ではない 関数の一覧 </li></ul><ul><ul><li>http://www.opengroup.org/onlinepubs/009695399/fun...
POSIX AIO –  シグナル通知 iocb->aio_fildes = … iocb->aio_buf  = … iocb->aio_nbytes = … iocb->aio_offset = … iocb->aio_sigevent.s...
POSIX AIO –  シグナル通知/注意点 <ul><li>シグナルセーフ である 関数の一覧 </li></ul><ul><ul><li>http://www.linux.or.jp/JM/html/LDP_man-pages/man7/...
libaio io_queue_init (AIO_MAXIO, &myctx); struct iocb *ioq[n]; for (i=0; i<=n; i++) { io_prep_pread (iocb, srcfd, iosize, ...
サンプルコードのありか <ul><li>http://klab.klab.org/trac/general/wiki/aio-copy </li></ul>
アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></u...
sival_ptr と sigval_ptr <ul><li>sigval union - /usr/include/sys/signal.h  </li></ul><ul><li>sival_ptr </li></ul><ul><ul><li...
AIO を使っているプロダクト <ul><li>lighttpd-1.5.0 (PRE RELEASE) </li></ul><ul><ul><li>Linux : libaio (io_submit + io_getevents) </li>...
POSIX AIO で扱えるファイルディスクリプタ <ul><li>regular file </li></ul><ul><li>名前付きパイプ </li></ul><ul><li>ソケット </li></ul><ul><li>なんでもおk <...
libaio で扱えるファイルディスクリプタ <ul><li>regular file </li></ul><ul><li>ソケットはダメ </li></ul><ul><li>名前付きパイプもダメ </li></ul>
では、 lighttpd はどこで libaio を使っているのか? <ul><li>tmpfs(/dev/shm/) にファイルを作る </li></ul><ul><li>tmpfs 上のファイルを mmap(2) する </li></ul>...
レベルトリガとエッジトリガ <ul><li>epoll(2) </li></ul><ul><ul><li>デフォルト :  レベルトリガ </li></ul></ul><ul><ul><li>EPOLLET :  エッジトリガ </li></u...
レベルトリガとエッジトリガ <ul><li>レベルトリガ </li></ul><ul><ul><li>越えている間はイベントが起こり続ける </li></ul></ul><ul><li>エッジトリガ </li></ul><ul><ul><li>...
レベルトリガとエッジトリガ <ul><li>レベルトリガ </li></ul><ul><ul><li>越えている間はイベントが起こり続ける </li></ul></ul><ul><li>エッジトリガ </li></ul><ul><ul><li>...
Syslets, Threadlets <ul><li>Syslets, Threadlets (≧2.6.24) </li></ul><ul><ul><li>http://lwn.net/Articles/219954/ </li></ul>...
参考文献 <ul><li>The C10K problem </li></ul><ul><ul><li>http://www.kegel.com/c10k.html </li></ul></ul><ul><ul><li>http://www.h...
おしまい
Upcoming SlideShare
Loading in...5
×

Aio

5,406

Published on

Published in: Technology, Education
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,406
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
32
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide
  • Aio

    1. 1. 非同期 I/O 概説 Introduction to Asynchronous I/O AIO, I/O Multiplexing…
    2. 2. 今日の目的 <ul><li>非同期 I/O とは何かを知る </li></ul><ul><li>非同期 I/O を使うと何がうれしいのかを知る </li></ul><ul><li>非同期 I/O を実現する手段(複数)を知る </li></ul>
    3. 3. アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></ul><ul><li>落穂ひろい </li></ul>
    4. 4. アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></ul><ul><li>落穂ひろい </li></ul>
    5. 5. ネットワークサーバのお仕事を考えてみる <ul><li>Web サーバとか </li></ul><ul><li>I/O (ネットワーク I/O 、ディスク I/O )に着目 </li></ul><ul><ul><li>リクエストを受ける(ネットワーク read ) </li></ul></ul><ul><ul><li>ディスクからコンテンツを読む(ディスク read ) </li></ul></ul><ul><ul><li>レスポンスを返す(ネットワーク write ) </li></ul></ul>
    6. 6. 一般的な I/O の特性 <ul><li>read(2)/write(2) </li></ul><ul><ul><li>いつでもデータが読める / 書けるとは限らない </li></ul></ul><ul><ul><li>準備ができるまで戻らない=待たされる </li></ul></ul><ul><li>「 I/O ブロッキング」 </li></ul>
    7. 7. ネットワークサーバ ×I/O <ul><li>ネットワークサーバ </li></ul><ul><ul><li>ネットワーク I/O 、ディスク I/O を伴う </li></ul></ul><ul><li>I/O ブロッキング </li></ul><ul><ul><li>I/O で待たされる </li></ul></ul><ul><li>単一の処理(リクエスト / レスポンス)を完了するまでに時間がかかる(待たされるので) </li></ul><ul><li>単位時間の処理能力が下がる </li></ul><ul><ul><li>並行度( concurrent )が下がる </li></ul></ul>
    8. 8. The C10K problem <ul><li>The C10K problem </li></ul><ul><ul><li>http://www.kegel.com/c10k.html </li></ul></ul><ul><ul><li>http://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem </li></ul></ul><ul><li>“ 「 C10K 問題」(クライアント 1 万台問題)とは、ハードウエアの性能上は問題がなくても、あまりにクライアントの数が多くなるとサーバがパンクする問題のこと” </li></ul><ul><li>同時処理数を上げるための、 I/O 戦略について説明しているドキュメント </li></ul>
    9. 9. C10K - I/O 戦略 <ul><li>1スレッド:1クライアントで、ブロッキング I/O </li></ul><ul><ul><li>× 各スレッドでスタックを消費する </li></ul></ul><ul><ul><ul><li>NPTL の場合 8MB/thread </li></ul></ul></ul><ul><li>1スレッド:多クライアントで、ノンブロッキング I/O (I/O 多重化 ) </li></ul><ul><ul><li>select, poll, epoll, kqueue, /dev/poll </li></ul></ul><ul><li>1スレッド:多クライアントで、 AIO </li></ul><ul><ul><li>POSIX AIO, libaio </li></ul></ul>非同期 I/O
    10. 10. アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></ul><ul><li>落穂ひろい </li></ul>
    11. 11. I/O モデルの整理 Synchronous Asynchronous Blocking Non-blocking read/write read/write (O_NONBLOCK) I/O multiplexing I/O 多重化 (select, poll) AIO 非同期 I/O (POSIX AIO, libaio) ~ Boost application performance using asynchronous I/O http://www-128.ibm.com/developerworks/linux/library/l-async/
    12. 12. I/O 多重化とは <ul><li>I/O 可能になった fd の集合を通知するしくみ </li></ul><ul><ul><li>通知後に、 read(2),write(2) を行う </li></ul></ul><ul><li>実装 </li></ul><ul><ul><li>select(2) </li></ul></ul><ul><ul><ul><li>I/O 可否の検査のためにすべての fd を走査する必要があるので、 fd が多いと効率が悪い </li></ul></ul></ul><ul><ul><ul><li>FD_SETSIZE (Linux だと 1024) までしか fd を監視できない </li></ul></ul></ul><ul><ul><li>poll(2) </li></ul></ul><ul><ul><ul><li>FD_SETSIZE の上限がない select(2) </li></ul></ul></ul><ul><ul><li>epoll(2) Linux, kqueue(2) FreeBSD, /dev/poll Solaris </li></ul></ul><ul><ul><ul><li>I/O 可能な fd だけ返却される </li></ul></ul></ul><ul><ul><ul><li>OS のよって実装がばらばら-> libevent </li></ul></ul></ul>
    13. 13. AIO とは <ul><li>非同期に I/O を行うしくみ </li></ul><ul><ul><li>通知時にはすでに read や write が完了している </li></ul></ul><ul><ul><li>read の場合はバッファにデータが入っている </li></ul></ul><ul><li>実装 </li></ul><ul><ul><li>POSIX AIO </li></ul></ul><ul><ul><ul><li>http://opengroup.org/onlinepubs/009695399/basedefs/aio.h.html </li></ul></ul></ul><ul><ul><ul><li>Linux, FreeBSD , Mac OS X , Solaris, HP-UX, AIX </li></ul></ul></ul><ul><ul><li>libaio </li></ul></ul><ul><ul><ul><li>http:// lse.sourceforge.net/io/aio.html </li></ul></ul></ul><ul><ul><ul><li>Linux 独自の実装 </li></ul></ul></ul>
    14. 14. I/O 多重化 vs AIO <ul><li>select(2) はブロックする ※タイムアウトは指定可能 </li></ul><ul><li>通知後に read(2) が必要=コンテキストスイッチ </li></ul>
    15. 15. I/O 多重化 vs AIO <ul><li>ブロックしない=ほかの処理を行える </li></ul><ul><li>シグナルかコールバックが非同期に呼ばれる </li></ul><ul><li>通知時には既にバッファに入ってる </li></ul>
    16. 16. アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></ul><ul><li>落穂ひろい </li></ul>
    17. 17. AIO の実装 – Linux 2.6 <ul><li>POSIX AIO – POSIX 準拠 </li></ul><ul><ul><li>aio_read / aio_write, aio_error, aio_return, … </li></ul></ul><ul><ul><li>通知方法は、スレッド( SIGEV_THREAD )とシグナル( SIGEV_SIGNAL )の両方に対応している </li></ul></ul><ul><ul><li>実はシステムコールじゃなくてライブラリ関数( librt ) </li></ul></ul><ul><ul><ul><li>裏でいくつかスレッドを作ってがんばってるっぽい </li></ul></ul></ul><ul><li>libaio – Linux 独自 </li></ul><ul><ul><li>io_queue_init, io_prep_pread / io_prep_pwrite, io_set_callback, io_submit, … </li></ul></ul><ul><ul><li>http://lse.sourceforge.net/io/aio.html </li></ul></ul><ul><ul><li>システムコール </li></ul></ul><ul><ul><li>POSIX AIO より性能は上 </li></ul></ul>
    18. 18. AIO の実装 – FreeBSD 6.2 <ul><li>POSIX AIO – POSIX 準拠 </li></ul><ul><ul><li>aio_read / aio_write, aio_error, aio_return, … </li></ul></ul><ul><ul><li>システムコール </li></ul></ul><ul><ul><li>通知方法は SIGEV_KEVENT のみ </li></ul></ul><ul><ul><ul><li>SIGEV_KEVENT: kqueue(2) と kevent(2) で通知 </li></ul></ul></ul><ul><ul><ul><li>SIGEV_THREAD 、 SIGEV_SIGNAL は使えない>< </li></ul></ul></ul>
    19. 19. アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></ul><ul><li>落穂ひろい </li></ul>
    20. 20. POSIX AIO – スレッド通知 iocb->aio_fildes = … iocb->aio_buf = … iocb->aio_nbytes = … iocb->aio_offset = … iocb->aio_sigevent.sigev_notify = SIGEV_THREAD ; iocb->aio_sigevent.sigev_notify_function = rd_done ; iocb->aio_sigevent.sigev_value.sival_ptr = iocb ; aio_read (iocb); /* void rd_done (sigval_t sigval) */ iocb = (struct aiocb *)sigval.sival_ptr; while ((rc = aio_error (iocb)) == EINPROGRESS); rc = aio_return (iocb); char *buf = (void *)iocb->aio_buf; struct aiocb の初期化 aiocb を取り出す データが詰まってる buf 返り値を得る エラー状態を確認 スレッドを起床して通知 コールバック関数 自分自身を格納 非同期処理をリクエスト
    21. 21. POSIX AIO – スレッド通知/注意点 <ul><li>スレッドセーフ ではない 関数の一覧 </li></ul><ul><ul><li>http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html#tag_02_09_01 </li></ul></ul>
    22. 22. POSIX AIO – シグナル通知 iocb->aio_fildes = … iocb->aio_buf = … iocb->aio_nbytes = … iocb->aio_offset = … iocb->aio_sigevent.sigev_notify = SIGEV_SIGNAL ; iocb->aio_sigevent.sigev_signo = SIGIO_READ ; iocb->aio_sigevent.sigev_value.sival_ptr = iocb ; aio_read (iocb); /* void rd_done (int signo, siginfo_t *info, void *context) */ iocb = (struct aiocb *)info->si_value.sival_ptr; while ((rc = aio_error (iocb)) == EINPROGRESS); rc = aio_return (iocb); char *buf = (void *)iocb->aio_buf; struct aiocb の初期化 aiocb を取り出す ☚ データが詰まってる buf 返り値を得る エラー状態を確認 シグナルで通知 ☚ 発生シグナルを指定 ☚ 自分自身を格納 非同期処理をリクエスト sigemptyset(&sigact_r.sa_mask); sigact_r.sa_flags = SA_SIGINFO; sigact_r.sa_sigaction = rd_done ; sigaction( SIGIO_READ , &sigact_r, NULL); シグナルハンドラ
    23. 23. POSIX AIO – シグナル通知/注意点 <ul><li>シグナルセーフ である 関数の一覧 </li></ul><ul><ul><li>http://www.linux.or.jp/JM/html/LDP_man-pages/man7/signal.7.html#lbAH </li></ul></ul>
    24. 24. libaio io_queue_init (AIO_MAXIO, &myctx); struct iocb *ioq[n]; for (i=0; i<=n; i++) { io_prep_pread (iocb, srcfd, iosize, offset); io_set_callback (iocb, rd_done); ioq[i] = iocb; } io_submit (myctx, n, ioq); io_queue_run (myctx); io_queue_wait(myctx, NULL); /* void rd_done(io_context_t ctx, struct iocb *iocb , long res,…) */ int iosize = iocb->u.c.nbytes; char *buf = iocb->u.c.buf; off_t offset = iocb->u.c.offset; 非同期イベント処理-> CB データが詰まってる buf コンテキストの初期化 iocb のセットアップ (read) コールバック関数のセット 非同期処理をリクエスト 非同期処理の完了を待つ
    25. 25. サンプルコードのありか <ul><li>http://klab.klab.org/trac/general/wiki/aio-copy </li></ul>
    26. 26. アジェンダ <ul><li>非同期 I/O を使う理由 </li></ul><ul><li>非同期 I/O とは? </li></ul><ul><li>AIO の実装を紹介 </li></ul><ul><li>AIO の使い方 </li></ul><ul><li>落穂ひろい </li></ul>
    27. 27. sival_ptr と sigval_ptr <ul><li>sigval union - /usr/include/sys/signal.h </li></ul><ul><li>sival_ptr </li></ul><ul><ul><li>POSIX, Linux </li></ul></ul><ul><li>si g val_ptr </li></ul><ul><ul><li>FreeBSD, Mac OS X </li></ul></ul>/* borrow from lighttpd-1.5.0 */ #if (defined(__FreeBSD__) || defined(__DragonFly__)) #define sival_ptr sigval_ptr #endif
    28. 28. AIO を使っているプロダクト <ul><li>lighttpd-1.5.0 (PRE RELEASE) </li></ul><ul><ul><li>Linux : libaio (io_submit + io_getevents) </li></ul></ul><ul><ul><li>POSIX : AIO (SIGEV_THREAD) </li></ul></ul><ul><ul><li>FreeBSD : × </li></ul></ul><ul><li>nginx-0.6.4 ( んぎんくす ) </li></ul><ul><ul><li>Linux : × (たぶん…) </li></ul></ul><ul><ul><li>FreeBSD : AIO (SIGEV_KEVENT) </li></ul></ul>io_queue_* を使っていない。 が、実は io_queue_* は io_setup や io_getevents のラッパーにすぎない
    29. 29. POSIX AIO で扱えるファイルディスクリプタ <ul><li>regular file </li></ul><ul><li>名前付きパイプ </li></ul><ul><li>ソケット </li></ul><ul><li>なんでもおk </li></ul>
    30. 30. libaio で扱えるファイルディスクリプタ <ul><li>regular file </li></ul><ul><li>ソケットはダメ </li></ul><ul><li>名前付きパイプもダメ </li></ul>
    31. 31. では、 lighttpd はどこで libaio を使っているのか? <ul><li>tmpfs(/dev/shm/) にファイルを作る </li></ul><ul><li>tmpfs 上のファイルを mmap(2) する </li></ul><ul><li>非同期に、 </li></ul><ul><ul><li>ファイルからデータを read して、 </li></ul></ul><ul><ul><li>mmap(2) した領域に write する </li></ul></ul><ul><li>tmpfs 上のファイルを sendfile(2) でソケットに送る </li></ul>read(2)+write(2) よりも mmap(2)+sendfile(2) のほうが早い。 なぜなら、カーネル内でコピーが行われるから。
    32. 32. レベルトリガとエッジトリガ <ul><li>epoll(2) </li></ul><ul><ul><li>デフォルト : レベルトリガ </li></ul></ul><ul><ul><li>EPOLLET : エッジトリガ </li></ul></ul>
    33. 33. レベルトリガとエッジトリガ <ul><li>レベルトリガ </li></ul><ul><ul><li>越えている間はイベントが起こり続ける </li></ul></ul><ul><li>エッジトリガ </li></ul><ul><ul><li>超えた / 下回ったときだけイベントが起こる </li></ul></ul>★ ★ ★ ★ ★ ★ ★ ★
    34. 34. レベルトリガとエッジトリガ <ul><li>レベルトリガ </li></ul><ul><ul><li>越えている間はイベントが起こり続ける </li></ul></ul><ul><li>エッジトリガ </li></ul><ul><ul><li>超えた / 下回ったときだけイベントが起こる </li></ul></ul>★ ★ ★ ★ ★ ★ ★ ★
    35. 35. Syslets, Threadlets <ul><li>Syslets, Threadlets (≧2.6.24) </li></ul><ul><ul><li>http://lwn.net/Articles/219954/ </li></ul></ul><ul><ul><li>http://www.cuspy.org/blog/2007/07/25/ </li></ul></ul>“ Syslets” はカーネル内で小さなプログラムを動作させるための手段であり、システムコールを非同期かつユーザー空間から出ずに実行する方法です。 “ Threadlets” はユーザー空間で非同期のコードを実行するメカニズムと同類です。 どちらのケースでも、コードの問い合わせがブロックしない限り同期的に実行されますが、もし何かを待たなければならない場合カーネルはスレッドを生成し ( スペアのスレッドが再利用される場合もある ) 、ユーザー空間でそのスレッドを実行します。 このパッチの最初の動機はメンテナンスに大変な手間が掛かる AIO のアプローチを使わずに、完全な非同期 I/O を実装を可能にすることでした。 以来、 syslets と threadlets はシステムコールの非同期実行を可能にしただけでなく、より多くのアプリケーションの対応が可能となりました。
    36. 36. 参考文献 <ul><li>The C10K problem </li></ul><ul><ul><li>http://www.kegel.com/c10k.html </li></ul></ul><ul><ul><li>http://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem </li></ul></ul><ul><li>Boost application performance using asynchronous I/O / IBM developerWorks </li></ul><ul><ul><li>http://www-128.ibm.com/developerworks/linux/library/l-async/ </li></ul></ul><ul><li>Kernel Asynchronous I/O (AIO) Support for Linux </li></ul><ul><ul><li>http:// lse.sourceforge.net/io/aio.html </li></ul></ul>
    37. 37. おしまい
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×