仮想化されたUbuntuの奇妙なプロセス動作

仮想化されたUbuntuの奇妙なプロセス動作

VirtualBoxを使用してWindows 8.1でUbuntu 14.04 LTSを実行しています。オペレーティングシステムにアクセスしていますが、次のプログラムで奇妙な結果が表示されます。

#include <stdio.h>
#include <unistd.h>
int main() {
printf("I'm the parent, my PID is %d, my parent is process %d\n",
getpid(), getppid());
fork();
printf("This sentence has been printed by process: %d my parent is process %d\n",
getpid(), getppid());
return 0;
}     

GCCでコンパイルして実行しました。その後、出力は次のようになります。

kocks@kocks-VirtualBox:~$ ./uno
I'm the parent, my PID is 3746, my parent is process 3507
This sentence has been printed by process: 3746 my parent is process 3507
kocks@kocks-VirtualBox:~$ This sentence has been printed by process: 3747 my parent is process 2857

問題は3番目の文にあります。私は「親プロセスは3746です」と予想しました。特に、数字(2857)は常に同じで、VMを再起動した後にのみ変更されます。追加するいくつかの点があります。

  1. wait()返す前に追加すると完璧に動作します。
  2. 仮想マシンを「プリンセス」しようとすると(2つのプロセッサ、メモリの追加など)、ランダムに正しい出力が返されることがあります。

では、問題は仮想マシンにあるようですが、そうですか?この問題をどのように解決できますか?

編集する デュアルブートでUbuntuでプログラムを実行すると、出力は次のようになります。

I'm the parent, my PID is 3186, my parent is process 2454 
This sentence has been printed by process: 3186 my parent is process 2454
This sentence has been printed by process: 3187 my parent is process 3186

どうやってこれができますか?

答え1

私はOS Xをホストとして使用し、クライアントごとに1つのCPUのみを割り当てる2つの仮想マシン設定でテストしました。

1 Ubuntu 14.04.2

この設定では、X Window環境での動作はOPの動作と一致します。

john@U64D:~$ ./a
I'm the parent, my PID is 2682, my parent is process 2632
This sentence has been printed by process: 2682 my parent is process 2632
john@U64D:~$ This sentence has been printed by process: 2683 my parent is process 1673

親プロセス1673は、ログアウトして再度ログインするまで同じままです。

john@U64D:~$ ./a
I'm the parent, my PID is 3787, my parent is process 3740
This sentence has been printed by process: 3787 my parent is process 3740
john@U64D:~$ This sentence has been printed by process: 3788 my parent is process 3107
./a
I'm the parent, my PID is 3790, my parent is process 3740
This sentence has been printed by process: 3790 my parent is process 3740
john@U64D:~$ This sentence has been printed by process: 3791 my parent is process 3107

3107初期化 - ユーザー

john@U64D:~$ ps -ef|grep 3107
john      3107  2911  0 15:07 ?        00:00:00 init --user

ただし、X以外の環境(例:tty1)では、結果はBarmarの答えと一致します。

2 Debian 7.8

この設定は、X 環境と X 以外の環境の両方に対する Barmar の回答と一致します。

ジョン@ Debian:~$ ./a

I'm the parent, my PID is 3455, my parent is process 3406
This sentence has been printed by process: 3455 my parent is process 3406
john@debian:~$ This sentence has been printed by process: 3456 my parent is process 1

結論として

OP観測は、基本X環境でセッション初期化を使用するUbuntuの結果です。セッション初期化の詳細を確認できます。ここ

答え2

使用しないと、wait()子供が走る前に親が終了する可能性があります。子プロセスが呼び出されると、getppid()親プロセスはすでに終了しているため、子プロセスが採用されますinit。一般的なUnix実装では、PIDはinit1なので、次のように期待できます。私の両親はプロセス1です。このようなことが起こった場合。しかし、明らかにVirtualBoxはこれを変更しました。

を使用すると、wait()終了する前に親が子が完了するのを待ちます。こうすれば、その子は決して孤児にならないでしょう。

関連情報