Fork(2)のマニュアルページから:
RETURN VALUE
On success, the PID of the child process is returned in the parent, and
0 is returned in the child. On failure, -1 is returned in the parent,
no child process is created, and errno is set appropriately.
フォークコールが失敗する理由について疑問に思っています。フォークが-1を返すケースシナリオは何ですか?
Cで標準のUnixシェルを書いています。エラーをどのように処理すればよいですか?
C APIでは、システムコールはエラーを示すために負の値を返し、errno
のエラーコードはエラーの性質に関する詳細情報を提供します。マニュアルページでは、システムで発生する可能性のあるエラーについて説明する必要があります。 2つの 標準 エラーコードがあります:
EAGAIN
は、使用可能なリソースが不足しているため、新しいプロセスを作成できないことを示します。何らかのメモリが不足しているか、ユーザーあたりまたは全体のプロセスの最大数などの制限に達しています。ENOMEM
は、ある種のメモリが不足しているために新しいプロセスを作成できないことを示します。 Linuxでは、ENOMEM
はカーネルメモリの不足を示し、ユーザーランドメモリの不足はEAGAIN
として報告されます。 OpenBSDでは、ENOMEM
はユーザーランドメモリの不足にも使用されます。要約すると、fork
は、使用可能なリソースが不足しているために失敗する可能性があります(おそらく、単純なメモリ不足ではなく、人為的な制限の形で)。
fork
が失敗したときのシェルの動作は、POSIXでは指定されていません。実際には、それらは異なるエラーステータスを返す傾向があります(pdkshで1、ashで2、bashで254、ksh93で258、tcshで1、zshはバグである0を返します)。 (学習演習ではなく)本番環境で使用するためにシェルを実装している場合は、 Austin Group メーリングリストでこれについて説明する価値があるかもしれません。
カーネルには、同時に実行できるプロセスの最大数を示すパラメーターNPROC
があることを知っています。すでに最大になっていて、別のカーネルを作成しようとすると、カーネルから拒否され、親に-1が返されると思います。
別の注意点として、カーネルには、MAXUPRC
パラメーターに格納されるユーザーごとのプロセスの制限もあります。上記と同じ取引が適用されます。
考えられる理由の1つは、クォータの制限またはシステム障害が原因で新しいプロセスを生成できないことです。
ソフトウェアを作成するとき、何かが失敗する理由を常に知っているとは限りませんが、うまくいかない場合にすべてのステップを処理する明確に定義された方法を持つことは常に良い考えです。