I am running Python 2.7 on a QNX system and I'm running into an issue where pexpect throws the following error:
ExceptionPexpect: isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?
The circumstances for this error are as follows: I have two files, pexpectTest.py
and testPexpectError.py
.
pexpectTest.py
import multiprocessing import pexpect import sys pexp = pexpect.spawn('python testPexpectError.py') pexp.delaybeforesend = False pexp.logfile = sys.stdout def test(): pexp.sendline('line') pexp.expect('>', timeout=None) pexp.close() mp = multiprocessing.Process(target=test) mp.start() mp.join()
testPexpectError.py
import time while 1: input = raw_input(">") print input if input == 'exit': break time.sleep(1)
When called from a multiprocessing.Process, the exception at the top of this post gets thrown. When called from the main thread, the exception does not get thrown.
My main questions are:
What is causing pexpect to react to the wait call in testPexpectError.py when expect is called from a multiprocessing.Process vs when expect is called in the main thread (if this even is the issue)?
Is there any way around this?
CodePudding user response:
Remember, the key distinguishing feature of multiprocessing
is that it spawns a function inside a separate process.
File descriptors are not shared across process boundaries (a child may get a copy of the parent's FDs, but this is an optional per-FD flag -- see https://docs.python.org/3/library/os.html#fd-inheritance describing the interface Python puts on top of that layer).
Likewise, parent/child relationships only apply to the original parent: You can use waitpid()
to reap a child process, but not a sibling (a fellow child of the same parent, which is the relationship your copy of python testPexpectError.py
and the multiprocessing
-spawned subprocess have here).
If you really need to use multiprocessing
here, move the spawn()
into your test()
function, so the child process is having its output and exit status read by its parent (rather than by a sibling), and everything will work.