4

基本的に次のような小さなpythonスクリプトがあります。

import os
import psutil

def processtree():
    pid = os.getpid()
    # have to go two levels up to skip calling shell and 
    # get to actual parent process
    parent = psutil.Process(pid).parent().parent()

    print 'Parent %s [PID = %d]' % (parent.name(), parent.pid)
    print '        |'
    for child in parent.children(recursive=True):
        if child.pid != pid:
            print '        - Child %s [PID = %d]' % (child.name(), child.pid)
        else:
            print '        - Child %s [PID = %d] (Self)' % (child.name(), child.pid)

if '__name__' == '__main__':
    processtree()

Windows でこのスクリプトを実行するbashと、他に何も実行されていないため、次のように表示されます。

Parent bash.exe [PID = 5984]
       |
       - Child bash.exe [PID = 5008]
       |
       - Child python.exe [PID = 3736] (Self)

この情報は正しいです。親の bash プロセスは PID 5984 で、python プロセスは 3736 です。ここで、PID 5984sleep 10000 &の子として実行されるように実行します。確認ps -aef | grep 5984したところ、そこにありました;:

$ ps -aef | grep 5984 | grep -v grep | grep -v ps
myuser    5984       1 con    May 12 /bin/bash
myuser    5080    5984 con  11:17:12 /bin/sleep
myuser    3948    5984 con  11:36:47 /bin/bash

ただし、スクリプトを再度実行すると、次のように表示されます。

Parent bash.exe [PID = 5984]
       |
       - Child bash.exe [PID = 7560]
       |
       - Child python.exe [PID = 5168] (Self)

sleep現在として表示されていても、親 bash プロセスの子として表示されませんps

新しい呼び出しシェルが作成されてから、bash.exe の子の PID が変更されていることに注意してください (これが発生する理由はわかりませんが、関連しているとは思いません)。スクリプトを再度呼び出したので、Python インタープリターの PID python processtree.py

何が間違っているのかわからず、しばらくこれを見つめていました。どんな助けでも大歓迎です...

4

1 に答える 1

3

コメントから投稿して、他の人がこれを未回答の未解決の質問と見なさないようにする

代わりに を使用する必要がありますparent = psutil.Process(pid).parent()

Unix では、 と の組み合わせforkによりexec、2 番目のbashプロセスがスリープに置き換えられます。

Windows は、プロセス作成のスポーン モデルに基づいています。これは、DEC VMS から継承されたレガシーです。(Dave Cutler は VMS と NT の両方の設計を担当しました。1988年には、多くの元 DEC エンジニアが彼に従って Microsoft に移りました。) NT カーネルは実際にforkexecを実装できます。

于 2015-07-03T21:45:24.610 に答える