python popen popen2

目前有一个查询程序 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 模块下有更强大的进程管理接口。

    rp, wp, ep = popen2.popen3("%s -e %s %s" % (addr2line_cmd, kernel_path, symbol_addr))
    addr2error = ep.readlines()
    addr2line = rp.readline().strip()
    ep.close()
    rp.close()
    wp.close(

但是在实际的编码过程中,因为popen隔断了各种输出,所以最后使用了os.system(cmd)
另外os.startfile()据说也可以,但是没有试。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值