У меня есть довольно простой сценарий python, который для этого вопроса сокращен до следующего:
#!/usr/bin/env python3
import os
print(os.getpid(), "a")
def main():
n_children = 10
n_it = 1
children = []
for x in range(n_children):
print(os.getpid(), "b", "x=", x)
pid = os.fork()
if pid == 0:
for i in range(n_it):
pass
exit(0)
children.append(pid)
print("started %d children doing %d iterations each"%(n_children, n_it))
err = 0
for pid in children:
r = os.wait()
if r[1] != 0:
print("wait", r)
err += 1
if err == 0:
print("ok")
else:
print("err")
exit(1)
if __name__ == '__main__':
print(os.getpid(), __name__, "start")
main()
print(os.getpid(), __name__, "end")
Если я запустил его из своей оболочки или из сценария, я получу ожидаемый результат:
16047 a
16047 __main__ start
16047 b x= 0
16047 b x= 1
16047 b x= 2
16047 b x= 3
16047 b x= 4
16047 b x= 5
16047 b x= 6
16047 b x= 7
16047 b x= 8
16047 b x= 9
started 10 children doing 1 iterations each
ok
16047 __main__ end
Пока все хорошо. Теперь, если я запускаю его из сценария xfstests (так AFAIK вызывал серию сценариев оболочки), я получаю очень странное поведение, когда кажется, что разветвление заставляет родительский процесс запускаться заново ... Я не могу воспроизвести его снаружи из xfstest. Это необъяснимо.
QA output created by 002
/home/aaptel/prog/xfstests-git/xfstests/tests/cifs/optest.py -u //localhost/test -o username=aaptel,password=aaptel,noperm,seal,vers=3.0,sec=ntlmsspi,mfsymlinks,actimeo=0,nosharesock -c 10 -i 1 /mnt/test /mnt/oplock
15911 a
15911 __main__ start
15911 b x= 0
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 b x= 3
15911 b x= 4
15911 b x= 5
15911 b x= 6
15911 b x= 7
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 b x= 3
15911 b x= 4
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 b x= 3
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 b x= 3
15911 b x= 4
15911 b x= 5
15911 b x= 6
15911 b x= 7
15911 b x= 8
15911 b x= 9
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 b x= 3
15911 b x= 4
15911 b x= 5
15911 b x= 6
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 b x= 3
15911 b x= 4
15911 b x= 5
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 b x= 3
15911 b x= 4
15911 b x= 5
15911 b x= 6
15911 b x= 7
15911 b x= 8
15911 a
15911 __main__ start
15911 b x= 0
15911 b x= 1
15911 b x= 2
15911 b x= 3
15911 b x= 4
15911 b x= 5
15911 b x= 6
15911 b x= 7
15911 b x= 8
15911 b x= 9
started 10 children doing 1 iterations each
ok
15911 __main__ end
Обратите внимание, как один и тот же PID (основной родительский процесс) печатает «a», « main start» и входит в l oop несколько раз .. .?!
Это как если бы fork () заставлял родительский процесс запускать скрипт заново вместо того, чтобы продолжить в месте вызова fork ().
Это на Linux с Python 3.6.10.