J'essaie d'utiliser des tuyaux pour communiquer entre les processus en python. Ces processus seront appelés à partir de différents threads, et n'auront donc pas nécessairement un accès direct à l'objet Popen
pour chaque processus. J'ai écrit un script ci-dessous, comme une simple preuve de concept, mais j'ai constaté que mon processus de réception ne se termine jamais.Comment fermer correctement un tube partagé par deux processus?
import os
import subprocess
import traceback
import shlex
if __name__ == '__main__':
(fd_out, fd_in) = os.pipe()
pipe_in = os.fdopen(fd_in, 'w')
pipe_out = os.fdopen(fd_out, 'r')
file_out = open('outfile.data', 'w+')
cmd1 = 'cat ' + ' '.join('parts/%s' % x for x in sorted(os.listdir('parts')))
cmd2 = 'pbzip2 -d -c'
pobj1 = subprocess.Popen(shlex.split(cmd1), stdout=pipe_in)
pobj2 = subprocess.Popen(shlex.split(cmd2), stdin=pipe_out,
stdout=file_out)
print 'closing pipe in'
pipe_in.close()
print 'closing pipe out'
pipe_out.close()
print 'closing file out'
file_out.close()
print 'waiting on process 2'
pobj2.wait()
print 'done'
Cela fonctionne correctement de plusieurs façons. Les blocs de données sont redirigés vers le second processus et le deuxième processus décompresse le flux et l'écrit dans un fichier. Je peux regarder les processus jusqu'à ce qu'ils semblent attendre (et ne rien faire), terminer le 2ème processus, et le fichier semble être complètement écrit. Donc, je me demande pourquoi le 2ème processus ne se termine jamais. Il semble qu'il ne réalise jamais que le flux d'entrée a été fermé. Comment puis-je fermer le tube correctement, afin que le processus sache se terminer?
[email protected]:/home/tmp/db$ python test.py
closing pipe in
closing pipe out
closing file out
waiting on process 2
^Z
[1]+ Stopped python test.py
[email protected]:/home/tmp/db$ bg
[1]+ python test.py &
[email protected]:/home/tmp/db$ jobs -l
[1]+ 31533 Running python test.py &
[email protected]:/home/tmp/db$ ps -fp 31533
UID PID PPID C STIME TTY TIME CMD
1000 31533 22536 0 15:22 pts/2 00:00:00 python test.py
[email protected]:/home/tmp/db$ lsof |grep $(pwd)
bash 3432 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
bash 22536 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
python 31533 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31536 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31536 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31537 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31537 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31538 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31538 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31539 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31539 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31540 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31540 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31541 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31541 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31542 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31542 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31543 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31543 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
pbzip2 31535 31544 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
pbzip2 31535 31544 david_clymer 1u REG 253,3 12255300000 397270 /home/tmp/db/outfile.data
lsof 31599 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
grep 31600 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
lsof 31602 david_clymer cwd DIR 253,3 483328 408117 /home/tmp/db
[email protected]:/home/tmp/db$ strace -p 31533
Process 31533 attached - interrupt to quit
wait4(31535, ^C <unfinished ...>
Process 31533 detached
J'imagine que je fais quelque chose de stupide. J'aimerais savoir quoi, et pourquoi.
Ahah! Il s'avère donc que l'utilisation de 'close_fds = True' résout ce problème et le fait fonctionner comme prévu. – vezult
@vezult Merci, je ne connaissais pas close_fds, mais c'est logique. – Neil