日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K, 12.1-RELEASE-K は、 プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K から 12.4-RELEASE-K, 13.0-RELEASE-K から 13.3-RELEASE-K, 14.0-RELEASE-K から 14.1-RELEASE-K は、全翻訳済み)
13.3-STABLE-K, 15.0-CURRENT-K は現在、作成中で日々更新されています。
Table of Contents
FORK(2) FreeBSD システムコールマニュアル FORK(2)
名称
fork -- 新しいプロセスを作成する
ライブラリ
標準 C ライブラリ (libc, -lc)
書式
#include <unistd.h>
pid_t
fork(void);
pid_t
_Fork(void);
解説
fork() 関数は、新しいプロセスの生成を行います。新しいプロセス (子プロセ
ス) は、次を除いて呼び出しているプロセス (親プロセス) の正確なコピーです:
• 子プロセスには、ユニークなプロセス ID があります。
• 子プロセスには、異なる親プロセス ID があります (すなわち、親プ
ロセスのプロセス ID)。
• 子プロセスには、親プロセスから継承されない kqueue(2) によって返
された記述子を除いて、親の記述子のそれ自体のコピーがあります。
これらの記述子は、同じ根本的なオブジェクトを参照します、つまり
それは、例えば、ファイルオブジェクトのファイルポインタが、子プ
ロセスと親プロセスの間で共有され、その結果、子プロセスの記述子
で lseek(2) することは、親プロセスでその後の read(2) または
write(2) に影響するかもしれません。また、この記述子のコピーは、
パイプをセットアップするのと同様に、新しく作成されたプロセスの
ための標準入力と出力を確立するためにシェルによって使用されま
す。
• 子プロセスのリソースの利用は、0 に設定されます。setrlimit(2) を
参照してください。
• すべてのインターバルタイマは、クリアされます。setitimer(2). を
参照してください。
• robust ミューテックスのリスト (pthread_mutexattr_setrobust(3)
を参照) は、子プロセスのためにクリアされます。
• pthread_atfork(3) 関数で確立された atfork ハンドラは、親プロセ
スと子プロセスで、親プロセスの fork の前と、子プロセスが作成さ
れた後に、適切に呼び出されます。
• 子プロセスには、親プロセスで呼び出しているスレッドに対応する、
ただ 1 つのスレッドがあります。プロセスに 2 つを以上のスレッド
があるなら、ロックされ、他のスレッドによって保持された他のリ
ソースは、解放されません、したがって、非同期シグナルにセーフな
関数 (sigaction(2) を参照) だけが execve(2) または同様の関数を
呼び出すまで子プロセスで動作することが保証されます。fork() の
FreeBSD の実装は、子プロセスで使用可能な malloc(3) と rtld(1)
サービスを提供しています。
fork() 関数は、非同期シグナルセーフではなく、親プロセスのキャンセルポイン
トを作成します。シグナルハンドラから安全に使用することはできず、
pthread_atfork(3) によって確立された atfork ハンドラは、非同期シグナル
セーフである必要はありません。
_Fork() 関数は、fork() と同様に新しいプロセスを作成しますが、非同期シグナ
ルセーフです。_Fork() は、atfork ハンドラを呼び出さず、キャンセルポイント
も作成しません。それは、シグナルハンドラから安全に使用することができます
が、ユーザ空間のサービス (malloc(3) または rtld(1)) は、マルチスレッドの
親プロセスから fork されるなら、子プロセスで利用可能ではありません。特
に、ダイナミックリンクを使用しているなら、_Fork() の後に子プロセスによっ
て使用されるすべてのダイナミックシンボルは、事前に解決していなければなり
ません。注意: 解決は、ダイナミックリンカに LD_BIND_NOW 環境変数を指定する
ことによってグローバルに行うことができるか、またはスタティックリンカ
ld(1) に -z now オプションを渡すことでバイナリごとに行うことができます、
または強制的にバインドするために _Fork() 呼び出しの前に各シンボルを使用す
ることによって行うことができます。
戻り値
正常に完了すれば、fork() と _Fork() は、子プロセスに値 0 を返し、親プロセ
スに子プロセスのプロセス ID を返します。そうでなければ、-1 の値が親プロセ
スに返され、子プロセスは、作成されず、グローバル変数 errno は、エラーを示
す値が設定されます。
使用例
次の例は、fork() が実際にどのように使用されるかの共通のパターンを表示しま
す。
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(void)
{
pid_t pid;
/*
* 子プロセスが stdio(3) を使用することが期待されるなら,
* 二重出力とその他の可能性のある問題を回避するために,
* 再利用される io ストリームの状態は, 親プロセスと
* 子プロセスの間で同期されなければなりません.
*/
fflush(stdout);
switch (pid = fork()) {
case -1:
err(1, "Failed to fork");
case 0:
printf("Hello from child process!\n");
/*
* stdout に書き込んだので, プロセスは, _exit(2)
* ではなく exit(3) を使用する必要があります.
* これによって, atexit(3) で登録されたハンドラは,
* 親プロセスで 1 回、子プロセスで 1 回, 計 2 回
* 呼び出されます. このような振る舞いが好ましくない
* なら, _exit(2) または _Exit(3) で子プロセスを
* 終了させることを考慮してください.
*/
exit(0);
default:
break;
}
printf("Hello from parent process (child's PID: %d)!\n", pid);
return (0);
}
そのようなプログラムの出力は、次の行に沿います:
Hello from parent process (child's PID: 27804)!
Hello from child process!
エラー
fork() システムコールは、次の場合に失敗し、子プロセスは、作成されません:
[EAGAIN] 実行に基づくプロセスの合計数のシステムの制限が超過しま
した。制限は、sysctl(3) MIB 変数 KERN_MAXPROC によって
与えられます。(制限は、スーパユーザを除いて、この値未
満の実際に 10 です)。
[EAGAIN] ユーザがスーパユーザでなく、シングルユーザによって実行
に基づくプロセスの合計数でシステムの制限が超過しまし
た。制限は、sysctl(3) MIB 変数 KERN_MAXPROCPERUID に
よって与えられます。
[EAGAIN] ユーザがスーパユーザでなく、resource 引数 RLIMIT_NPROC
に対応するソフトリソース制限が超過しました
(getrlimit(2) を参照)。
[ENOMEM] 新しいプロセスのための十分なスワップ領域がありません。
関連項目
execve(2), rfork(2), setitimer(2), setrlimit(2), sigaction(2), vfork(2),
wait(2), pthread_atfork(3)
歴史
fork() 関数は、Version 1 AT&T UNIX で登場しました。
_Fork() 関数は、fork() 実装が非同期シグナルセーフでなければならないという
要件が削除されるとともに Austin Group によって定義されました。_Fork() 関
数は、FreeBSD 14.0 で登場しました。
FreeBSD 13.2 August 5, 2021 FreeBSD 13.2