os.pipe learning tips
os.pipe() 典型用法:#!/usr/bin/pythonimport os, sysprint "The child will write text to a pipe and "print "the parent will read the text written by child..."# file descriptors r, w for reading an
·
os.pipe() 典型用法:
#!/usr/bin/python
import os, sys
print "The child will write text to a pipe and "
print "the parent will read the text written by child..."
# file descriptors r, w for reading and writing
r, w = os.pipe()
processid = os.fork()
if processid:
# This is the parent process
# Closes file descriptor w
os.close(w)
r = os.fdopen(r)
print "Parent reading"
str = r.read()
print "text =", str
os.waitpid(processid, 0) # wait for child process terminate
sys.exit(0)
else:
# This is the child process
os.close(r)
w = os.fdopen(w, 'w')
print "Child writing"
w.write("Text written by child...")
w.close()
print "Child closing"
sys.exit(0)
Please note, this usage is only intend for the simplest scenario: The child process need to output something to parent process, and with more complex scenarios, there will be more complex code clips. Will describe this later.
Refer to:http://www.tutorialspoint.com/python/os_pipe.htm and http://jiangzhixiang123.blog.163.com/blog/static/27802062201171105139619/
os.pipe() 的代码实现:
Tracing into module of os (os.py), and find there nothing about function of pipe(), except the following code clips:
_names = sys.builtin_module_names # names of built-in modules, with Windows OS, there will be an item of 'nt' within this tuple, while on Posix (Unix, linux), there will be an item of 'posix'
# Note: more names are added to __all__ later.
__all__ = ["altsep", "curdir", "pardir", "sep", "extsep", "pathsep", "linesep",
"defpath", "name", "path", "devnull",
"SEEK_SET", "SEEK_CUR", "SEEK_END"]
def _get_exports_list(module): # this function will get all the attributes which not starts with "_"
try:
return list(module.__all__)
except AttributeError:
return [n for n in dir(module) if n[0] != '_']
if 'posix' in _names:
name = 'posix'
linesep = '\n'
from posix import * # import all the attributes of posix, within which pipe() is implemented as well as other posix system calls
try:
from posix import _exit
except ImportError:
pass
import posixpath as path # that's where os.path come from
import posix
__all__.extend(_get_exports_list(posix)) # add all the attributes of posix to var __all__
del posix
We can find that, function of pipe() is implemented within this built-in module posix. Currently will just skip the source code of this.
os.pipe() 的其他用法:
Another scenario of using os.pipe() is subprocess. The following source code comes from subprocess.py
class Popen(object):
def __init__(self, args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0):
"""Create new Popen instance."""
_cleanup()
self._child_created = False
if not isinstance(bufsize, (int, long)):
raise TypeError("bufsize must be an integer")
if mswindows:
if preexec_fn is not None:
raise ValueError("preexec_fn is not supported on Windows "
"platforms")
if close_fds and (stdin is not None or stdout is not None or
stderr is not None):
raise ValueError("close_fds is not supported on Windows "
"platforms if you redirect stdin/stdout/stderr")
else:
# POSIX
if startupinfo is not None:
raise ValueError("startupinfo is only supported on Windows "
"platforms")
if creationflags != 0:
raise ValueError("creationflags is only supported on Windows "
"platforms")
self.stdin = None
self.stdout = None
self.stderr = None
self.pid = None
self.returncode = None
self.universal_newlines = universal_newlines
# Input and output objects. The general principle is like
# this:
#
# Parent Child
# ------ -----
# p2cwrite ---stdin---> p2cread
# c2pread <--stdout--- c2pwrite
# errread <--stderr--- errwrite
#
# On POSIX, the child objects are file descriptors. On
# Windows, these are Windows file handles. The parent objects
# are file descriptors on both platforms. The parent objects
# are None when not using PIPEs. The child objects are None
# when not redirecting.
(p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite) = self._get_handles(stdin, stdout, stderr) # !!!this is what we need
def _get_handles(self, stdin, stdout, stderr):
"""Construct and return tupel with IO objects:
p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
"""
p2cread, p2cwrite = None, None
c2pread, c2pwrite = None, None
errread, errwrite = None, None
# stdin can be:
# None, will inherite from the pareent;
# a file descirptor, a positive number;
# a file-object; or
# PIPE
if stdin is None:
pass
elif stdin == PIPE:
p2cread, p2cwrite = os.pipe() #p2cread: child process will read input from this end of this pipe, p2cwrite: parent process will write something to pipe with this end. and will be closed by child process.
elif isinstance(stdin, int):
p2cread = stdin
else:
# Assuming file-like object
p2cread = stdin.fileno()
if stdout is None:
pass
elif stdout == PIPE:
c2pread, c2pwrite = os.pipe() # c2pread will be used by parent processto read the output of child process, which will be closed by the child process, while, c2pwrite will be used by child process to output it's outputs to parents
elif isinstance(stdout, int):
c2pwrite = stdout
else:
# Assuming file-like object
c2pwrite = stdout.fileno()
if stderr is None:
pass
elif stderr == PIPE:
errread, errwrite = os.pipe()
elif stderr == STDOUT: # stderr has another more options of STDOUT.
errwrite = c2pwrite
elif isinstance(stderr, int):
errwrite = stderr
else:
# Assuming file-like object
errwrite = stderr.fileno()
return (p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite)
As we can see, if we indicate the parameters of stdin, stdout and stderr to Popen() as PIPE, there will be 3 pipes new created with os.pipe() of which the return values (file descriptors) are assigned to six vars, which will be used and handled by child process.
更多推荐
已为社区贡献1条内容
所有评论(0)