7

CS クラスのシェルをプログラミングしていますが、ユーザーが「&」文字を渡すと、プロジェクトの一部でプロセスがバックグラウンドで実行されます。

プロセスがフォアグラウンドで実行されている場合、プロセスは単にフォアグラウンドにexecvpあるため、端末の制御下に置かれます。ただし、バックグラウンド プロセスの場合は、プロセスの実行を開始した後でメイン シェルに制御を戻す必要があります。システムコールtcsetpgrp(pid_t)が引数として渡されたプロセスをフォアグラウンドに配置することは理解していますが、その使用方法がよくわかりません。

バックグラウンド プロセスの場合、後で呼び出す必要がありますtcsetpgrpか? execvpもしそうなら、呼び出すだけでシェルの pid を取得できgetpidますか?

4

3 に答える 3

10

tcsetpgrp()個々のプロセスではなく、プロセス グループで機能します。あなたがしたいことはこれです:

  1. 新しいパイプラインを作成するときは、 を呼び出しsetpgid()て、パイプラインのすべてのメンバーを新しいプロセス グループに配置します (パイプラインの最初のプロセスの PID を PGID として使用します)。(パイプラインとは、シェルが次のようなリクエストを受け取ったときに開始するプロセスのシーケンスですls | grep foo | wc -l。最も単純なパイプラインには、プロセスが 1 つしかありません)。通常、 をsetpgid(0, 0)呼び出す前に、パイプラインの最初のプロセスから呼び出しexec()ます。

  2. tcsetpgrp()フォアグラウンドにあるプロセス グループを管理するために使用します。プロセス グループをフォアグラウンドからバックグラウンドに移動する場合、シェル自体のプロセス グループをフォアグラウンド プロセス グループとして設定します。これgetpgid(0)はシェルで取得できます。

  3. シェルがバックグラウンドにある場合waitpid()、プロンプトを表示するのではなく、ブロック呼び出しを使用して子プロセスが終了するのを待つ必要があります。フォアグラウンド パイプラインのすべてのプロセスが終了すると、再びフォアグラウンドに戻ります (プロンプトが表示されます)。

  4. シェルがフォアグラウンドにある場合、プロンプトを表示する直前に子プロセスのステータスを確認するためにおよびフラグを指定waitpid()して呼び出す必要があります。これにより、子プロセスが停止または終了したときに通知され、ユーザーに通知されます。WNOHANGWUNTRACED

于 2012-05-28T04:51:58.150 に答える
-1

&シェルがバックグラウンドを使用してプロセスを開始する場合、$!シェル変数には子プロセスの PID が含まれます。次に、そのプロセスにシグナルを送信するか、 を使用してプロセスwait $!が完了するのを待ちます。

于 2012-05-28T06:23:47.967 に答える
-2

子プロセスを作成するには、 forkを確認する必要があります。次に、exec子で使用して、目的のコマンドを実行します。

于 2012-05-28T04:27:22.250 に答える