目前有一个查询程序 get_user_id 是用C写的,python需要调用这个程序:使用 get_user_id  "用户名" 可以得到输出: "ID0002451".
  
  在python中使用管道可以方便的调用这个进程并得到它的标准输出:
 
  get_user_id 是C写的,程序大概的框架如下:得到一个命令行参数,然后根据参数打印其相应的id:
 
 
int main(int argc , char* args[]) 

    char * name = args[1] 
    printf("%s",getid(name) ); 

 
 
  
  python程序调用的片段如下:
 
    pipe = os.popen( "get_user_id " + "myname") 
 
    user_id    = pipe.read() 
     
      pipe.close()
 
  python是这样调用get_user_id程序的。 首先python会启动一个子进程,然后读入子进程的标准输出,最后结束子进程。 这里的主要的开销是进程的启动和撤销,管道之间的通信是非常快的。
 
  如果get_user_id调用得不太频繁,则这种调用方式没有问题;若get_user_id调用得很频繁,以致它的性能成为了系统的瓶颈,这就有必要优化了。优化的方法是使得get_user_id子进程常驻内存,python父进程可以使用write/flush和readline的方法和子进程通信;程序结束时撤销子进程。
  
  进程常驻内存后,python只需要启动一次子进程就可以满足任意次的查询。不过带来的麻烦是get_user_id程序需要重写:将它改为在循环中接收标准输入,把结果送往标准输出,另外约定一个特殊的输入(如"EOF"),子进程收到这个输入后退出循环。
  
  get_user_id改后
  
 
int main(int argc , char* args[]) 
      char name[512]; // buff
    while( scanf("%s", name)  ){
          if (!strcmp(name,"EOF")) return 0;
        printf("%s\n",getid(name) ); 
      }

 
 
  
  这个C程序先接受标准输入,判断输入是否结束为结束标志,如果是则返回,否则打印用户ID。
  
  Python应该如何调用这个进程呢?使用popen()得到的pipe对象只支持write或者read操作,而不能同时读和写。
 
  需要同时允许读写操作,使用popen2()。该函数返回一个包涵两个元素的tuple,这两个元素依次是写管道(即可向目标进程写入标准输入)和读管道(即读进程的标准输出)。
  如果需要和上述C程序打交道,则应该这样打开管道
 
  pipe_out , pipe_in = popen2( " get_user_id " , "wr");
  
  "wr"表示次管道需要先写后读。
 
  具体例子如下:进行10000次查询
 
   
import os 
 
if __name__ == "__main__": 
     
    pipe_in , pipe_out = popen2("get_user_id", "wr"); 
    for i in range(10000) 
        pipe_in.write("myname"); 
        pipe_in.write("\n"); #需要换行符
        pipe_in.flush(); #需要清空缓冲区
         
        userid = pipe_out.readline(); #读入结果
 
 
 上述情况需要注意的是,为了和进程顺利交互,一般需要flush,防止io缓冲;尽量写入和读入整行,方便控制管道交互过程。
 
 根据笔者试验显示:使用常驻内存的进程进行10000次调用,比不常驻内存的进程快得多,前者耗费的时间大约是后者的1/5,不过这个结果只是笔者的特例。请读者分析自己的应用场合,看看如何使用python强大的管道工具。
 
 ps,python还有popen3,可打开进程的stdin,stdout和stderr,更好更强大。另外subprocess 模块下有更强大的进程管理接口。

Python和其他进程的管道通信方式--popen和popen2的比较的更多相关文章

  1. python中的进程、线程(threading、multiprocessing、Queue、subprocess)

    Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...

  2. Python多进程(1)——subprocess与Popen()

    Python多进程方面涉及的模块主要包括: subprocess:可以在当前程序中执行其他程序或命令: mmap:提供一种基于内存的进程间通信机制: multiprocessing:提供支持多处理器技 ...

  3. python之路-进程

    博客园 首页 新随笔 联系 管理 订阅 随笔- 31  文章- 72  评论- 115    python之路——进程   阅读目录 理论知识 操作系统背景知识 什么是进程 进程调度 进程的并发与并行 ...

  4. Python的subprocess子进程和管道进行交互

    在很久以前,我写了一个系列,Python和C和C++的交互,如下 http://blog.csdn.net/marising/archive/2008/08/28/2845339.aspx 目的是解决 ...

  5. Python::OS 模块 -- 进程参数

    os模块的简介请参看 Python::OS 模块 -- 简介 os模块的文件和目录操作 Python::OS 模块 -- 文件和目录操作 os模块的进程管理 Python::OS 模块 -- 进程管理 ...

  6. Python 线程(threading) 进程(multiprocessing)

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  7. python并发_进程_multiprocessing

    多进程基础, 主要是用了 multiprocessing模块 : 在一个python进程中开启子进程,start方法和并发效果. import time from multiprocessing im ...

  8. Python 线程和进程和协程总结

    Python 线程和进程和协程总结 线程和进程和协程 进程 进程是程序执行时的一个实例,是担当分配系统资源(CPU时间.内存等)的基本单位: 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其 ...

  9. Linux进程间的通信方式和原理

    进程的概念 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放.可以认为进程是一个程序的一次执行过程. 进程通信的概念 进程用户空间是 ...

随机推荐

  1. VueX源码分析(2)

    VueX源码分析(2) 剩余内容 /module /plugins helpers.js store.js helpers要从底部开始分析比较好.也即先从辅助函数开始再分析那4个map函数mapSta ...

  2. PAT Basic 1077

    1077 互评成绩计算 在浙大的计算机专业课中,经常有互评分组报告这个环节.一个组上台介绍自己的工作,其他组在台下为其表现评分.最后这个组的互评成绩是这样计算的:所有其他组的评分中,去掉一个最高分和一 ...

  3. selenium2用AutoIt上传文件

    1.标签是input,如下图所示: WebElement e1= driver.findElement(By.id("load"));//输入要上传文件的地址e1.sendKeys ...

  4. UVa 12167 & HDU 2767 强连通分量 Proving Equivalences

    题意:给出一个有向图,问最少添加几条有向边使得原图强连通. 解法:求出SCC后缩点,统计一下出度为0的点和入度为0的点,二者取最大值就是答案. 还有个特殊情况就是本身就是强连通的话,答案就是0. #i ...

  5. Oracle数据库的日常使用命令

    1.     启动和关闭数据库 sqlplus /nolog; SQL >conn / as sysdba;(上面的两条命令相当于sqlplus ‘/as sysdba’) SQL >st ...

  6. Struts2报错:No result defined for action xxx and result input

    case如下: 1. 后台程序要升级, 修改了一些功能,但是没有修改或者添加action的参数. 2. 数据库需要升级,执行了一些sql,修改过action的值. 3. 当修改某个已经存在的记录,然后 ...

  7. 常用类--Date日期类,SimpleDateFormat日期格式类,Calendar日历类,Math数学工具类,Random随机数类

    Date日期类 Date表示特定的时间,精确到毫秒; 构造方法: public Data() public Date(long date) 常用方法: public long getTime() pu ...

  8. 【java基础 12】HashMap中是如何形成环形链表的?

    导读:经过前面的博客总结,可以知道的是,HashMap是有一个一维数组和一个链表组成,从而得知,在解决冲突问题时,hashmap选择的是链地址法.为什么HashMap会用一个数组这链表组成,当时给出的 ...

  9. 记账APP市场分析

    文/欧小慧(简书作者)原文链接:http://www.jianshu.com/p/281fcdce3baa著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 一.市场环境 1.理财记账类用 ...

  10. Welcome-to-Swift-19类型嵌套(Nested Types)

    枚举类型常被用于实现特定类或结构体的功能.也能够在有多种变量类型的环境中,方便地定义通用类或结构体来使用,为了实现这种功能,Swift允许你定义类型嵌套,可以在枚举类型.类和结构体中定义支持嵌套的类型 ...