2012-06-11 167 views
2

請爲popen()建議好的替代方法來執行shell命令,然後讀取輸出。替代popen管道來執行程序並讀取輸出

編輯:替代必須是無fork()電話。因爲我的服務器已經佔用了太多內存。然後ffmpeg還需要內存和進程大小增加!並且我每次都遇到問題以fork()來記憶權重服務器。

回答

4

如果您擔心在分叉時複製父進程的內存,則需要使用vfork()-特殊版本的「fork」,它不會複製父進程的內存,但需要分叉進程立即發出execve()

+0

請問,請添加示例如何使用它作爲替代popen()?我目前的popen代碼在這裏http://stackoverflow.com/questions/10962044/correct-code-non-blocking-pipe-with-popen。奇怪的是,popen在默認情況下不使用vfork()。「 – abrahab

+0

」vfork()函數還首先執行子進程,並在子進程終止時恢復父進程。「 - 我的服務器和用戶將等待10分鐘而'ffmpeg'執行? :)陷阱 – abrahab

+2

@abrahab:請仔細閱讀手冊頁。父母在孩子呼叫'execve'後立即恢復。 – 2012-06-11 19:56:04

0

這是我在學校的教導:

int main(int argc, char *argv[]) { 

    int pipefd[2]; 
    pid_t cpid; 
    char buf; 


    if (pipe(pipefd) == -1) { 
     perror("pipe"); 
     exit(EXIT_FAILURE); 
    } 

    cpid = fork(); 
    if (cpid == -1) { 
     perror("fork"); 
     exit(EXIT_FAILURE); 
    } 

    if (cpid == 0) { 
     /* Child reads from pipe */ 
     close(pipefd[1]); 

     //make the standard input to be the read end 
     pipefd[0] = dup2(pipefd[0], STDIN_FILENO); 

     system("more"); 

     write(STDOUT_FILENO, "\n", 1); 
     close(pipefd[0]); 


    } else { 

     /* Parent writes argv[1] to pipe */ 
     close(pipefd[0]); 
     /* Close unused read end */ 

     pipefd[1] = dup2(pipefd[1], STDOUT_FILENO); 

     system("ps aux"); 
     /* Wait for child */ 
     wait(NULL); 
     exit(EXIT_SUCCESS); 
    } 

    return 0; 
} 

此產卵兩個過程,一個執行「的ps aux」,輸出輸送到運行「更多」的另一種。

+0

我不能fork()我的服務器。它已經使用太多的內存 – abrahab

+1

在這種情況下,你被卡住了,因爲'popen'只是包裝了通常的'fork' /'exec'成語。 – dmckee

+0

@dmckee賓果!也許,也許吧!因爲它給2-3打電話popen一個接一個,通常服務器是200-300 mbs。好。如何解決這個問題?我應該怎樣使用那個沒有fork()的exec?是的,似乎我必須找到替代popen() – abrahab