forkとファイルハンドル
UNIX系のOSでは,
「複製」
- 注1)
- UNIX系OSでは,
OSが提供する機能とライブラリが提供する機能を分けて考え, 前者を 「システムコール」, 後者を 「ライブラリコール」 と呼びます。 - 注2)
- ほとんどのOSでは,
Copy-on-Writeという手法を使ってメモリの複製処理を遅延させることで, forkの負荷を抑えるようになっています。 - 注3)
- ファイル内のシーク位置やファイルロックの所有権を管理する単位です。
- 注4)
- Perlの
「ファイルハンドル」 は, ファイル記述子を扱いやすい形にラップしたものです。
forkとDBIの誤用例
「SQLiteのデータベースファイルが壊れた」
SQLiteは,
MySQLの場合はTCPソケット
my $dbh = DBI->connect(...);
...
my $pid = fork;
die "fork failed:$!"
unless defined $pid;
# 両プロセスで同一のハンドルを使用 ⇒ エラー
if ($pid == 0) {
# 子プロセス
$dbh->do(...);
...
}
$dbh->do(...);
forkしたあとはリソースを解放すべし
親プロセスと子プロセスの両方から同じファイルにアクセスしたい場合は,
open my $fh, '<', ...;
...
my $pid = fork;
die "fork failed: $!"
unless defined $pid;
if ($pid == 0) {
# 子プロセス側ではファイルにアクセスしないからclose
close $fh;
...
exit(0);
}
# 親プロセス
my $line = <$fh>;
...
この例では子プロセス側でcloseを呼び出し,
- 注5)
- オープンファイル記述は,
それにひも付けられたファイル記述子が1つもなくなった際に閉じられます。