python popen popen2

來源:互聯網
上載者:User

目前有一個查詢程式 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 iin 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()據說也可以,但是沒有試。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.