system与popen函数的效率

时间:2022-09-20 16:54:32

 我们在程序中希望执行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函数执行结构

 system与popen函数的效率

 popen函数执行结果:

 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;
}