最終編集:2019年11月6日
バージョン:gccのバージョン5.4.0 20160609(Ubuntuの〜16.04.11 5.4.0-6ubuntu1)
まず、プロセスID
各プロセスは、独自の非負の整数のID、タイプがあるpid_t
プロセスが終了するかは、差がほとんどのオペレーティング・システムの複雑遅れている、そのファイルとハンドルである、プロセスIDシステムが再利用されます。殺されますアルゴリズムを用いて、この新しいプロセスを回避するために、以前に停止されているプロセス。(順次ダウン使用)のために誤解されます。
いくつかの特定のプロセスは、例えばID = 0、スケジューリング処理(交換処理スワッパ)、ID = INITプロセス1.初期化プロセスは、すべてのプロセスの祖先である、システムです。
1.1関連する関数
pid_t getpid(void); // 获取当前进程的 ID
pid_t getppid(void); // 获取父进程的 ID
二、フォーク機能
fork関数は、新しいプロセスを作成するために使用することができ、新たなプロセスは、相対的な現在のプロセスの子は、現在のプロセスが新しいプロセスの親であると呼ばれます。
pid_t fork(void);
フォーク二回返されたら呼ばれる。二度の違いを返すためには、新しい親が子プロセスIDを返す0子が返すということです
- プロセスは、複数のサブプロセスを持つことができますが、システムは関数ではありませんすべての子プロセスIDを取得することができます;:新しい親は、子プロセスID原因を返します。
- その理由は、子供は0の値を返します。子プロセスができ
getppid
、親プロセスIDを取得し、(カーネルスワップを使用した場合の交換プロセス上のID 0は永遠に、親プロセスの子プロセスが0であることは決してありません)。 - 戻り値は0が異常を示し未満であります
フォーク親プロセスと子プロセスの後の命令は、サブプロセスがの親である。続けてコピー。しかし、レプリケーション・テクノロジー(コピーオンライト)の書き込みは、親と子のゾーンのシェアを、多くのリアライズを使用してフォークした後、しかし、面積変化読み取り専用の状態、親または子はあなたが地域に変更を加えたいとき、カーネルはコピーとして、地域のコピー親や子プロセスになります。(誰が変更を行った、誰コピーしています)。
フォーク注文後のスケジュール親子プロセスはどのようなカーネルのスケジューリングアルゴリズムに応じて、不確実です。
2.1父と息子のプロセスの違い:
先に述べたように、子プロセスは親プロセスのコピーですが、それでも次のような違いがあります。
- 異なる戻り値をフォーク。
- 異なるIDプロセス;
- 親プロセスのIDが異なっています。
- tms_utime / tms_stime / tms_cutime子プロセス値/ tms_ustimeが0に設定されています。
- 子供は親によって設定されていない継承ファイルロックを行います。
- 未処理の目覚まし時計子プロセスがクリアされる;(保留信号がクリアされます)
- 未処理の信号は、子プロセスが空のセットに設定されている設定します。
2.2フォーク使用シナリオ
- 親が自分のフォーク要求を受信した後、要求を処理するために子プロセスを聞かせて、そのようなウェブサービス、要求のための親プロセスが待機するように、自分自身を複製したい、親プロセスの下で要求を待ち続けます。
- このようなシェル端末のような異なるプログラムを実行する工程;
コード例2.3
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int globvar = 6;
char buf[] = "a write to stdout \n";
int main(int argc, char **argv)
{
int var;
pid_t pid;
var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf) - 1) != sizeof(buf) - 1)
{
perror("write error");
}
printf("before fork \n"); // not flush stdout
if ((pid = fork()) < 0)
{
perror("fork error ");
}
else if (pid == 0) // child
{
globvar++;
var++;
}
else // parent
{
sleep(2); // 等待子进程先执行
}
printf("pid = %d, glob = %d, var = %d \n", getpid(), globvar, var);
exit(0);
}
結果:
a write to stdout
before fork
pid = 6053, glob = 7, var = 89
pid = 6052, glob = 6, var = 88
複数のファイルの内容を印刷するために内部文書にリダイレクトフォークプリント結果、フォークの前にコールにfflush()ストリームをフラッシュし
- 端末は、標準出力デバイスである\ nは、バッファがフラッシュがある場合、ラインバッファ出力デバイスは、標準モードであります
- ファイルが完全にバッファモード、フルモードのバッファである\ nは改行だけの役割であります
三、のvfork機能
この関数は、唯一の理解のために、欠陥があります
配列と同じ値を返すは、フォークコールをvforkのが、両方の意味的に異なります。
vfork関数は、プロセスの目的は、新たなexec関数で、新しいプロセスを作成します。のvfork子プロセスをプロセスの目的は、幹部を呼び出すことですので、親プロセスのアドレス空間を完全に、過去に複製されません。ただし、子プロセスのexecまたは終了する前に、子プロセスはある程度の効率を改善する、親プロセスの空間で実行されています。
しかし、子プロセスが親プロセスのデータを変更しない、または他の関数を呼び出す、または戻すには、no execを/終了すると、不明なエラーがあります。のvforkの優先順位は、子が返されることを保証するために、しかし子供はアクションの親に依存している場合これは、デッドロックになっただろう。
1は、のvforkを使用しないこと、それを言って