O'Reilly Japan Community Blog

このblogには、オライリーWebサイト協力者からの寄稿記事や、独自のインタビュー、レポート記事などを掲載します。

http://www.oreilly.co.jp/community/blog/images/union/pg_high_logo.png

プロセスがブロックする要因の一つにファイルI/Oがあります。これを同期I/Oと言いますが、POSIXではAIO(非同期 I/O、Asynchronous I/O)も定義しており、I/O中でもプロセスがブロックせず他の処理を進められるようになります。 本記事ではバッファキャッシュからファイル I/Oを解説し、Linuxのio_submit(2)を用いたPOSIX準拠のAIOライブラリを試作してみます。

ファイルI/Oとバッファキャッシュ

io_submit(2)ではDirect I/Oを用いますが、ライブラリの試作へ進む前にまずファイルI/Oのバッファ(バッファキャッシュ)について整理します。実は単にバッファと言ってしまうと誤解される場面が多くあり、例えばプログラミング入門一般としてファイルI/Oを取り上げる際には、

  • CPUの動作は速い。ディスクの動作は遅い。
  • 両者の間に速度差を緩和する緩衝地帯を設けないと、CPUの速度が犠牲にされてしまう。
  • このため、ファイルバッファを用いる。

といった説明があり、よく以下のようなサンプルコードが提示されます。

ファイルI/Oサンプルコード

main()
{
    # define SZ 16
    int fd;
    char buffer[SZ];

    fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);

    memset(buffer, 'a', SZ);
    write(fd, buffer, SZ);
}

先ほどの説明の後でbufferという名前の配列を見ると、これがCPUとディスクの速度差を緩和する緩衝体(バッファ)の役割をするもなのかと思ってしまいそうです。しかし現代の一般的な環境では、このbufferにはあまりそのような意味合いはなく、単なる作業用のメモリ領域に過ぎません。細部を説明する前に、あと2つサンプルコードを挙げます。以降のサンプルコードは付属のソースファイル一式に含まれているので、詳細はそちらを参照してください。

http://www.oreilly.co.jp/community/blog/images/union/pg_high_logo.png

>> (1)よりつづく

本記事のサンプルコードは、以下のリンクよりダウンロードすることができます。記事と合わせてご参照ください。
[ サンプルコード ]

子プロセスの同期/非同期

4epoll、5epoll-multiへのダミー処理追加には、いくつかの注意点があります。1baseと同じように、epollによるイベントループがその場で子プロセスの終了を待つようにすると、1つのダミー処理の終了を他のセッションが待つことになってしまいます。 これはepollによる、イベントループのI/Oの多重性を損なう大きな問題です( 図1.9 )。

図1.9 epoll の多重性を損ねるダミー処理追加

epoll2-fig9.png

(セッションCは割愛)

http://www.oreilly.co.jp/community/blog/images/union/pg_high_logo.png

「インターネットサーバでのPthreadとepoll」の記事(以下、前記事と呼びます)を書いた時点では、手元の環境がプアなためマルチプロセス/マルチスレッドを採用したサンプルプログラムの真価を発揮させられず、適切に比較できませんでしたが、その後デュアルコアマシンを借りることができたので、改めて比較してみました。 また、比較の際にサンプルプログラムに追加したダミー処理ではシグナルも使用したので、やはりLinuxに追加された signalfd(2) もepollによるイベントループで処理してみました。

本記事のサンプルコードは、以下のリンクよりダウンロードすることができます。記事と合わせてご参照ください。
[ サンプルコード ]

前記事のサンプルプログラム

前記事 ではHTTPサーバを例に並列性/多重性のサンプル実装を5種類提示しました。簡単に振り返ります。サンプルプログラムがデュアルコアシステム上で動作しており、HTTPリクエストがほぼ同時に3件届いた場合のインタリーブ例を挙げてみます。毎回必ずこの通りにインタリーブされるわけではなく、あくまでもそれぞれの動作の違いを示すための一例です( 図1.1 から 図1.5 )。 また、5epoll-multiはCPU数-1個の4epoll(相当)を子プロセスとして起動しますが、デュアルコアシステムでは子プロセスの4epollを1つしか起動せず、4epollとの比較がしにくくなるため、今回は測定用にCPU数分の4epollの子プロセスを起動することにします。

http://www.oreilly.co.jp/community/blog/images/union/pg_high_logo.png

>>(1)よりつづく
前回は単純な実装からマルチスレッド、スレッドプールと順に見て行きました。今回はいよいよepollを使った実装を紹介します。

epoll例- 4epoll.c

多重I/Oすなわち select(2) / poll(2) によるイベントループはマルチスレッドが普及する以前から利用されていました。 select(2) / poll(2) は複数のファイルディスクリプタ(ソケット)を調べ、I/O可能なものを返すシステムコールです。ソケットに対する読み取りはデフォルトではデータがなければブロック(データが到着するまで待つ)しますが、事前にI/O可能かを確認しておけばブロックすることはありません。1システムコールで複数のソケットを調べられる点も重要で、1プロセスで複数のクライアントに並行して対応できるようになります。しかし当然ながら、対象ソケット数の増加に応じて処理量が増えます。システムコールの実行時間がかかるだけではなく、ユーザ空間でもその結果を1ソケットづつ確認しながら処理を進めるため、性能劣化が問題となり、以前からこの問題が指摘されていました。Linuxでは poll(2) を拡張したepollインタフェース( epol_create(2) , epoll_ctl(2) , epoll_wait(2) )を実装しており、ファイルディスクリプタ数が多い場合の性能劣化を防いでいます。

前掲のもっとも単純なサンプル1base.cを、epollを用いて多重I/O化してみます。

http://www.oreilly.co.jp/community/blog/images/union/pg_high_logo.png

本連載ではシステムコールプログラミングの例も掲載していく予定ですが、本記事ではLinuxに追加されたepollを採りあげ、インターネットサーバでのPthread利用と比較してみます。

はじめに

マルチスレッドプログラミングが普及し、POSIX threadも制定され、Pthreadの利用は目新しいものではなくなりましたが、スレッドにまつわる迷信や誤った認識を、だいぶ減ったとはいえ、今でもたびたび耳にします。例として、

  • スレッドはプロセスよりも軽いので、多数作成しても軽快に動作する
  • スレッドはプログラミングを簡単にしてくれ、1つの処理だけに集中できる

などがあります。しかし、これらは常に真であるとは限りません。本記事ではマルチスレッドの概念や入門を繰り返すのではなく、その利用方法をHTTPサーバのサンプル実装を基に考察します。更にLinuxに追加された独自機能のepollインタフェースを用いて、マルチスレッドを見直すサンプルを実装してみます。

[Programmer's High]

UnionMount

AUFS/UnionFSがunion内のメンバをディレクトリとするのに対し、UnionMountでのメンバはブロックデバイス(すなわちマウントとしてunion機能実装)です。もっとも大きな違いはその実装方針にあり、UnionMountはより上位に位置するVFS内でunion機能を実現しようとしています( 図6 )。

ファイルシステムとしてのunion実装と比較すると、VFS内でメンバ内から処理対象を選択決定する点が大きく異なります。このため、 vfs_mkdir() などVFSヘルパ関数を再度コールする必要がなくなります。

[Programmer's High]

はじめに

平成21年春のLinux Storage & Filesystems Workshopで、LinuxカーネルにUnionMountという機能を実装することについて話し合われました。

UnionMountとは、かつてのSunOSに実装されていたTranslucent(Transparent)FilesystemやBSDのunion mountに相当する機能で、すでにディスクをマウントしているディレクトリ(マウントポイント)に別のディスクを重ねてマウントし、1つのマウントポイントから2台のディスクを同時に使用可能にするものです。例えばLiveCD(HDDへインストールせずにCD/DVD/FlashのみでLinuxを起動し、使用可能にする環境)などではこの機能を積極的に利用しています。

この記事ではLinuxカーネルにこの機能を実装するこれまでの試みと、前述の話し合いの結果としてLinux Kernel Mailing Listへ投稿されたパッチシリーズについて考察します。

keith_peters.jpg

「神の書」として知られる『ActionScript 3.0 アニメーション』の著者、Keith Peters氏の最新作『詳解 ActionScript 3.0アニメーション――衝突判定・AI・3DからピクセルシェーダまでFlash上級テクニック』が、1月23日、ついにオライリー・ジャパンから発売されました。発売がアナウンスされた直後、なんと予約だけでAmazon.co.jpのPC書ランキング入りを果たすなど、ActionScriptユーザーの熱い注目を集めています。 昨年11月に来日された際には、オライリー・ジャパンのオフィスにも立ち寄っていただきました(写真はその際のものです。Keithさんの左胸に注目!)。とても物静かで真摯なお人柄に、オライリーのスタッフも一目でファンになってしまいました。
今回、この『詳解 ActionScript 3.0アニメーション』刊行に先立って、Keithさんにメールインタビューを行いました。Keithさんのプライベートから、「神の書」と呼ばれるほどの書籍を書くまでに読んできた書籍や学習法などについてお話していただいております。

8回にわたってお届けしてきたこのシリーズも、いよいよ最終回。今回はその他の新しい機能、さらに、まつもとさんの口からは次のバージョンの話も飛び出します。

ラムダ

目立つ機能としては、「->」によるラムダ(λ)を入れたり、「.()」による呼び出しを入れたということですね、やっぱり関数型言語の影響が大きく、ラムダをこんな記号(->)で導入しました。

― まずこの話があったときは、まず最初に何があったかというと、「ラムダ」って書きづらいと。

1.8だとラムダメソッドってのがあって、lambdaだっけ、(綴りに)自信がないけど。Lispの人たちはそれこそ湯水のように使うけれど、普通のプログラマにはなじみがないし、読みにくい、書きにくい、長いメソッド名どうよって話があって。

あと、メソッドって再定義できるじゃないですか。「lambda」って書いても、本当にラムダを返すのか自信がない。ラムダじゃないものが返せてしまうかもしれない。いろんな最適化のことを考えると、こういうものは言語組み込みであった方がうれしいよねって思って、この2点から新しい記法を取り入れました。
ただエライ不評で、「この記号λに見えないじゃん」って。ターミナルっぽいフォントで表示して横に傾けるとλに見える、って言うとみんな笑ってくれるけど、それでも迫害は止まらないんです。

Ruby 1.9で注目の新機構、M17N(多言語化)を、まつもとさん、卜部さんのお二方が語ります。M17Nとは何か、どんなメリットがあるのか、M17Nが実装されたことで開かれる可能性とは?

Ruby 1.9では文字列の抽象度が上がった

Ruby 1.8ではすべてがバイト列だったんです。で、Ruby 1.9ではコードポイント1と対になっている文字を表現するようになりました。ちょっと抽象度があがりました。

ですから、これからは"ABCあいう"という文字列の0番目を取ると「A」という文字を返します。で、3文字目から1文字を取ると、変なバイトではなくて「あ」という文字を返します。

― 3番目というのはゼロから数えて3番目のことですね。

ゼロから...皆さん分かりますよね。数字はゼロから数えますよね。