I have a fairly simple python script, reduced to the following for this question:
#!/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")
If I run it from my shell, or from a script I get this expected output:
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
So far so good. Now if I run it from a xfstests script (so AFAIK called throught a series of shell scripts) I get a very strange behaviour where it seems forking makes the parent process start over... I cannot reproduce it outside of xfstest. It is unexplicable.
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
Notice how the same PID (main parent process) prints "a", "main start" and goes in the loop multiple times...?!
It is as if fork() makes the parent process start the script over instead of continuing at the fork() call location.
This is on Linux with Python 3.6.10.