1. 程式人生 > >system與popen函式的效率

system與popen函式的效率

 我們在程式中希望執行shell命令的時候首先想到的system函式,這個函式很簡單,但有一個嚴重的問題,就是他的執行方式,效率上可能不高。

        system函式首先建立一個新的程序,然後在新的程序中執行exec函式去執行我們的shell命令,然後阻塞等待shell命令執行完後,返回到呼叫函式,system之所以要建立新的程序,是因為,exec函式的呼叫會結束呼叫程序,從呼叫exec函式開始,程序就切換到執行shell命令的程序,無法回到呼叫exec的程序繼續執行程式的餘下部分。所以system就會新建程序去執行exec,exec結束掉system建立程序,返回的時候,將返回值送給呼叫system的程序。換句話說,system建立的程序就是為了給exec函式結束用的。
但我也查了相關資料,linux對system函式做了很好的優化,在system建立程序的時候,不會像建立普通程序那樣消耗系統的資源,system程序只有用到資料的時候,系統才為其分配,如果只是單純的執行shell命令,效率還是很高。
但我總覺得,每次執行個shell命令都呼叫system很不舒服,尤其是線上程中建立一個新的程序更是感覺很怪。linux中存在另一種執行shell命令的方法,就是管道,我就想測試一下,popen與system的效率誰更高。
        小程式如下:使用system與popen都執行1000次ls -l 命令,並將輸出指向 /dev/NULL(即不在控制檯顯示輸出結果)。

#include<iostream>
#include<stdio.h>
#include <stdlib.h>
#include<deque>
#include<sys/time.h>
using namespace std;
timeval start,end;
double timeuse;
void time()
{
    gettimeofday( &end, NULL );
    timeuse = (1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec -/ start.tv_usec)/1000000;
    printf("time used: %f s/n", timeuse);
}
int main(int argc, char** argv)
{

    gettimeofday(&start,NULL);
    for(int i=0;i<1000;i++)
    {
        //system("ls -l >/dev/null 2>&1  ");
        popen( "ls -l >/dev/null 2>&1 ", "r" );
    }
    time();
    return 0;
}

 system函式執行結構

 

 popen函式執行結果:

 

        如圖所示,當使用system函式的時候對cpu的佔用很大,但對記憶體的消耗很少,執行時間是14秒左右,

當使用popen的時候,對cpu的消耗很小,但記憶體的使用直線上升,執行時間是9秒左右,速度明顯提升。我的測試

很可能片面不準確,希望有時間再進行其他方面的比較。

/*
  * 執行指定命令串cmd_str
  * cmd_str: 命令串
  * output: 命令執行結果輸出
  * return: -1:failed
  *                0:success
*/

int execl_cmd(char *cmd_str, char *output)
{
        char buf[1024];
        FILE *fp;
 
        sprintf(buf, cmd_str);
        fp = popen(buf, "r");
        if( fp == NULL )
        {
                printf("popen() error!/n");
                return -1;
        }
        while(fgets(buf, sizeof(buf), fp))
        {
                if (output != NULL)
                        strcat(output,buf);
        }
        pclose(fp)
        return 0;
}