• python code mudule,pipe,stdin,stdou,IMPORTANT


    http://docs.python.org/library/code.html

    http://codeidol.com/python/python3/Parallel-System-Tools/Pipes/

    http://www.linuxjournal.com/article/2156

    Python:os模块的进程管理
    2009-07-09 11:59

    1. 有两种方式来实现并发性,一种方式是让每个“任务"或“进程”在单独的内在空间中工作,每个都有自已的工作内存区域。不过,虽然进程可在单独的内存空间中执行,但除非这些进程在单独的处理器上执行,否则,实际并不是“同时”运行的。是由操作系统把处理器的时间片分配给一个进程,用完时间片后就需退出处理器等待另一个时间片的到来。另一种方式是在在程序中指定多个“执行线程”,让它们在相同的内存空间中工作。这称为“多线程处理”。线程比进程更有效,因为操作系统不必为每个线程创建单独的内存空间。

    2. 新建进程用os.fork函数。但它只在POSIX系统上可用,在windows版的python中,os模块没有定义os.fork函数。相反,windows程序员用多线程编程技术来完成并发任务。

    3. os.fork函数创建进程的过程是这样的。程序每次执行时,操作系统都会创建一个新进程来运行程序指令。进程还可调用os.fork,要求操作系统新建一个进程。父进程是调用os.fork函数的进程。父进程所创建的进程叫子进程。每个进程都有一个不重复的进程ID号。或称pid,它对进程进行标识。子进程与父进程完全相同,子进程从父进程继承了多个值的拷贝,如全局变量和环境变量。两个进程的唯一区别是fork的返回值。子进程接收返回值0,而父进程接收子进程的pid作为返回值。

    4. 用os.fork创建的子进程和父进程作为异步的并发进程而单独执行。异步是指它们各行其是,相互间不进行同步;并发是指它们可同时执行。所以我们无法知道子进程和父进程的相对速度。

    5. os.wait函数用于等待子进程结束(只适用于UNIX兼容系统)。该函数返回包含两个元素的元组,包括已完成的子进程号pid,以及子进程的退出状态,返回状态为0,表明子进程成功完成。返回状态为正整数表明子进程终止时出错。如没有子进程,会引发OSError错误。os.wait要求父进程等待它的任何一个子进程结束执行,然后唤醒父进程。

    6. 要指示父进程等候一个指定的子进程终止,可在父进程中使用os.waitpid函数(只适用于unix兼容系统)。它可等候一个指定进程结束,然后返回一个双元素元组,其中包括子进程的pid和子进程的退出状态。函数调用将pid作为第一个参数传递,并将一个选项作为第二个选项,如果第一个参数大于0,则waitpid会等待该pid结束,如果第一个参数是-1,则会等候所有子进程,也就和os.wait一样。

    7. 用os.system 和 os.exec函数族来执行系统命令和其它程序。os.system使用shell来执行系统命令,然后在命令结束之后把控制权返回给原始进程;os.exec函数族在执行完命令后不将控制权返回给调用进程。它会接管python进程,pid不变。这两个函数支持unix和windows平台。

    8. os.popen()函数可执行命令,并获得命令的stdout流。函数要取得两个参数,一个是要执行的命令,另一个是调用函数所用的模式,如“r"只读模式。os.popen2()函数执行命令,并获得命令的stdout流和stdin流。函数返回一个元组,其中包含有两个文件对象,一个对象对应stdin流,一个对象对应stdout流。

    9. 进程使用IPC机制在进程间传递信息,一种IPC机制是“管道”,它是一种类似于文件的对象,提供单向通信渠道。父进程可打开一个管道,再分支一个子进程。父进程使用管道将信息写入(发送到)子进程,而子进程使用管道从父进程读取信息。在python中使用os.pipe函数创建管道。

    10. os._exit()类似于sys.exit(),但它不执行任何的清除工作(例如刷新缓冲区)。所以os._exit()尤其适用于退出子进程。如果程序使用sys.exit(),操作系统会回收父进程或其它子进程可能仍然需要的资源。传给os._exit()函数的参数必须是进程的退出状态。退出状态为0,表示正常终止。

    11. 进程也可用信号进行通信。所谓“信号”,是操作系统采取异步方式传给程序的消息。如CTRL+C会传递一个“中断信号”,通常该信号导致程序中止。然而程序完全可以指定用不同的行动来响应任何一个信号。在信号处理中,程序要接收信号,并根据那个信号采取一项行动。错误(例如向已关闭管道写入)、事件(例如计时器变成0)以及用户输入(例如按ctrl+c)都会产生信号。

    12. 针对每个信号,每个python程序都有一个默认的信号处理程序。例如,假定python解释器收到一个信号,该信号指出程序试图向已关闭的管道写入,或者用户敲入一个键盘中断,python就会引发一个异常。发生异常后,程序既可使用默认处理程序,也可使用自定义处理程序。

    13. signal.signal函数为中断信号注册一个信号处理程序。函数要获得两个参数:一个信号和一个对应于信号处理程序的函数。

    14. 在unix/linux系统中,子进程终止后,会保留在进程表中,让父进程知道子进程是否正常终止。如果创建大量子进程,但在终止后没有从进程表中移除它们,进程表便会积累越来越多的死进程,这些进程称为“zombies”(僵尸进程),消除僵尸进程的操作称为“reaping”,这是通过os.wait和os.waitpid函数实现的。

    18.2. 良好的编程习惯

    1. 进程应关闭不需要的管道端,因为操作系统限制了可同时打开的文件说明符数量。

    18.3. 移植性提示

    1. 并不是所有操作系统都能从一个正在运行的程序创建单独的进程,所以,进程管理是移植性最差的一项python特性。

    2. 每个系统都定义了特有信号集。signal是依赖于具体平台的模块,其中只包含系统定义的信号。

      reference:http://hi.baidu.com/giftangellong/blog/item/fe5dc630a749f410ebc4afa2.html

       

       

      python fork 收藏

      fork 是 python linux下 os 模块下的一个方法,用来创建一个子进程。今天遇到这个问题,所以找文章来稍微了解一下。以下来自http://www.myelin.co.nz/post/2003/3/13/#200303135。不当之处多指教。

      1、有时,程序在一个进程中运行可能会遇到一些问题。如进程可能会占用过多的内存或者打开太多的文件,或者根本无法运行。

      2、一般来说,需要将进程分为两个,在子进程中执行一些代码,然后向父进程总返回结果。

           这个过程是通过管道来实现的。os.pipe()创建一个管道。一个管道包括两个端,一个读(父进程)一个写(子进程)。子进程将结果写入写端,然后关闭之。父进程从读端读出。

          以os.fork()创建新进程,复制所有文件描述符。则父子进程都有了管道的读端和写端的拷贝。直到管道一端的所有拷贝都被关闭,那么管道才关闭,因而在创建子进程之后需要调用os.close()关闭父进程的写端。

         所以,运行过程是:

                 ---创建管道

                 ---创建子进程。

         子进程:

                 ----需要关闭管道读端

                 ----开始执行

                 ----向写端写入结果

                 ----进程死亡

        父进程:

                 ----关闭管道写端

                 ----从读端读取数据直到子进程死亡或者关闭

                 ----调用waitpid方法确保子进程已经被撤销(在FreeBSD中不这么做,那么子进程永远不会被死亡)

                 ----进程输出

      3、代码

      #!/usr/bin/env python

      import os, sys

      print "I'm going to fork now - the child will write something to a pipe, and the parent will read it back"

      r, w = os.pipe()           # r,w是文件描述符, 不是文件对象

      pid = os.fork()
      if pid:
          # 父进程
          os.close(w)           # 关闭一个文件描述符
          r = os.fdopen(r)      # 将r转化为文件对象
          print "parent: reading"
          txt = r.read()
          os.waitpid(pid, 0)   # 确保子进程被撤销
      else:
          # 子进程             
          os.close(r)
          w = os.fdopen(w, 'w')
          print "child: writing"
          w.write("here's some text from the child")
          w.close()
          print "child: closing"
          sys.exit(0)

      print "parent: got it; text =", txt

      note here 







      Re: Subprocess confusion: how file-like must stdin be?

      Cameron Laird
      Fri, 18 Aug 2006 05:10:51 -0700

      In article <[EMAIL PROTECTED]>,
      Nick Craig-Wood  <[EMAIL PROTECTED]> wrote:
      >Dennis Lee Bieber <[EMAIL PROTECTED]> wrote:
      >>  On Thu, 17 Aug 2006 17:16:25 +0000, [EMAIL PROTECTED] (Cameron Laird)
      >>  declaimed the following in comp.lang.python:
      >> 
      >> > Question:
      >> >   import subprocess, StringIO
      >> > 
      >> >   input = StringIO.StringIO("abcdefgh\nabc\n")
      >> 
      >>      Here you override the builtin function "input()"
      >> >       # I don't know of a compact, evocative, and
      >> >       # cross-platform way to exhibit this behavior.
      >> >       # For now, depend on cat(1).
      >> >   p = subprocess.Popen(["cat"], stdout = subprocess.PIPE, 
      >> >                            stdin = response)
      >> 
      >>      Here you specify the non-existant "response" 
      >
      >Assume the OP meant to write this
      >
      >>>> import subprocess, StringIO
      >>>> inp = StringIO.StringIO("abcdefgh\nabc\n")
      >>>> p = subprocess.Popen(["cat"], stdout = subprocess.PIPE, stdin = inp)
      >Traceback (most recent call last):
      >  File "<stdin>", line 1, in ?
      >  File "/usr/lib/python2.4/subprocess.py", line 534, in __init__
      >    (p2cread, p2cwrite,
      >  File "/usr/lib/python2.4/subprocess.py", line 830, in _get_handles
      >    p2cread = stdin.fileno()
      >AttributeError: StringIO instance has no attribute 'fileno'
      >>>> 
                              .
                              .
                              .
      Yes; my apologies for the confusion I introduced by "editing
      for publication", and doing it badly.
      
      Your interactive session does indeed exhibit the behavior that
      puzzles me.  My expectation was that StringIO and the std* 
      parameters to Popen() were made for each other; certainly there
      are many cases where stdout and stderr can be redirected *to* a
      StringIO.  Is it simply the case that stdin demands a more
      file-like object?  While that disappoints me, I certainly can
      program around it.  My question, then:  does stdin effectively
      require something really in the filesystem, or perhaps the
      stdout of a previous subprocess?  Is there no built-in way to
      feed it an in-memory construct?
      -- 
      http://mail.python.org/mailman/listinfo/python-list
      



      Re: Subprocess confusion: how file-like must stdin be?

      Laurent Pointal
      Fri, 18 Aug 2006 06:55:59 -0700

      Cameron Laird a écrit :
      > In article <[EMAIL PROTECTED]>,
      > Nick Craig-Wood  <[EMAIL PROTECTED]> wrote:
      >> Dennis Lee Bieber <[EMAIL PROTECTED]> wrote:
      >>>  On Thu, 17 Aug 2006 17:16:25 +0000, [EMAIL PROTECTED] (Cameron Laird)
      >>>  declaimed the following in comp.lang.python:
      >>>
      >>>> Question:
      >>>>   import subprocess, StringIO
      >>>>
      >>>>   input = StringIO.StringIO("abcdefgh\nabc\n")
      >>>     Here you override the builtin function "input()"
      >>>>       # I don't know of a compact, evocative, and
      >>>>       # cross-platform way to exhibit this behavior.
      >>>>       # For now, depend on cat(1).
      >>>>   p = subprocess.Popen(["cat"], stdout = subprocess.PIPE, 
      >>>>                            stdin = response)
      >>>     Here you specify the non-existant "response" 
      >> Assume the OP meant to write this
      >>
      >>>>> import subprocess, StringIO
      >>>>> inp = StringIO.StringIO("abcdefgh\nabc\n")
      >>>>> p = subprocess.Popen(["cat"], stdout = subprocess.PIPE, stdin = inp)
      >> Traceback (most recent call last):
      >>  File "<stdin>", line 1, in ?
      >>  File "/usr/lib/python2.4/subprocess.py", line 534, in __init__
      >>    (p2cread, p2cwrite,
      >>  File "/usr/lib/python2.4/subprocess.py", line 830, in _get_handles
      >>    p2cread = stdin.fileno()
      >> AttributeError: StringIO instance has no attribute 'fileno'
      >                       .
      >                       .
      >                       .
      > Yes; my apologies for the confusion I introduced by "editing
      > for publication", and doing it badly.
      > 
      > Your interactive session does indeed exhibit the behavior that
      > puzzles me.  My expectation was that StringIO and the std* 
      > parameters to Popen() were made for each other; certainly there
      > are many cases where stdout and stderr can be redirected *to* a
      > StringIO.  Is it simply the case that stdin demands a more
      > file-like object?  While that disappoints me, I certainly can
      > program around it.  My question, then:  does stdin effectively
      > require something really in the filesystem, or perhaps the
      > stdout of a previous subprocess?  Is there no built-in way to
      > feed it an in-memory construct?
      
      As this is a pipe at OS level, there may be no other way than using
      os-level tools (ie. real files with fileno), maybe creating an anonymous
      pipe, writing to it (relying on pipe buffering by the OS to avoid the
      creation of a writer thread), and giving this pipe (which should have a
      fileno) to the subprocess.Popen stdin parameter.
      Such a construction (pipe/writer thread) would be welcome as standard
      subprocess tool.
      
      
      A+
      
      Laurent.
      
      -- 
      http://mail.python.org/mailman/listinfo/python-list
      

  • 相关阅读:
    mysql常用命令
    使用MyBatis Generator自动创建代码(dao,mapping,poji)
    基于SSH框架的学生公寓管理系统的质量属性
    对于SSH框架的选择
    Hibernate的查询方式总结
    关于C/S模式开发的学习笔记
    window10系统安装SQL数据库和小蝴蝶的问题
    基于框架的图书管理系统开发的质量属性
    实验一 框架的选择及其原因
    软件体系架构的认识
  • 原文地址:https://www.cnblogs.com/lexus/p/1832902.html
Copyright © 2020-2023  润新知