os.pipe learning tips

来源:互联网 发布:淘宝网童装购物街 编辑:程序博客网 时间:2024/05/19 18:43

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 and writingr, 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 


And we'll see the function self._get_handles() would be like this:

        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.

0 0
原创粉丝点击