2010-08-09 53 views
1

我必須定期讀取重定向到文件的標準輸出的內容。請幫我解決問題。定期讀取使用dup2重定向到管道的標準輸出內容的問題

我詳細的問題是,我在第一個線程兩個紗線,我必須執行交流文件 它不斷將輸出寫入到標準輸出(即寫的Hello World在無限循環),並在第二個線程 我必須找回從標準輸出週期性地逐行輸出並存儲在緩衝區中。

以下是上述要求的代碼:請建議我是我的方法嗎? 以及如何實現entryOpThread()方法,以便它將定期讀取stdout的內容 是否應該使用read()系統調用或getLine()或其他方法從 管道逐行讀取(stdout被重定向到此管)。 在這個例子中,exec線程正在執行test.c,它連續地在stdout上輸出hello world, ,所以根據我的要求,我必須逐行讀取這個輸出行(「Hello world」),並將它存儲在outputthread中緩衝 //

#include<iostream> 
#include<pthread> 
#include<unistd.h> 
#include<sys/wait.h> 
const int MAX_LENGTH=100; 
using namespace std; 

//! file descriptor to duplicate the system standard input 
int inputPIPE[2]; 



//! file descriptor to duplicate the system standard output 
int OutputPipe[2]; 

//!Thread to retrieve output 
//! 
pthread_t OpThread; 

//!Thread to execute script 
//! 
pthread_t ExecThread; 


//! entry point of the exec thread 
void *entryExecThread(void * obj) 
{ 
    //create a child process to launch the script 
    int lPid; 
    lPid=fork(); 
    //connect read end of the pipe to the standard input 
    if(dup2(inputPIPE[0],STDIN_FILENO)==-1) 
    { 
     //throw exception 
    } 

    //connect write end of the pipe to the standard output 
    if(dup2(OutputPipe[1],STDOUT_FILENO)==-1) 
    { 
     //throw exception 
    } 
    if(lPid==0) 
    { 



     execvp("./test",NULL); 
    } 

    else 
    { 
     int mProcessId=lPid; 
     waitpid(mProcessId,NULL,0); 
    } 
    return NULL; 

} 

//! entry point of the output thread 
void *entryOpThread(void * obj) 
{ 
    //read contents of stdout periodically 
    char *lMssg=new char[MAX_LENGTH]; 
    read(OutputPipe[0],lMssg,MAX_LENGTH); 

    FILE *fd=fdopen(OutputPipe[0],"r"); 
    int lBufferLength=MAX_LENGTH; 
    /* while(true) 
     { 
      getline(&lMssg,(size_t *)&lBufferLength,fd); 
      // push message to the output buffer 
      if (lMssg !=NULL) 
      { 
       pthread_mutex_lock(&mOutputBufferMutex); 
       mOutputBuffer.push(lMssg); 
       pthread_mutex_unlock(&mOutputBufferMutex); 
      } 
     } 
    */ 

} 
int main() { 

    //call to pipe system call 
    if(pipe(inputPIPE)==-1) 
    { 
     printf("ERROR IN OPENING FILE \n"); 
    } 
    if(pipe(OutputPipe)==-1) 
    { 
     printf("ERROR IN OPENING FILE\n "); 
    } 

    //CREATE OUTPUT THREAD TO RETRIEVE OUTPUT 

    if (pthread_create(&OpThread,0,entryOpThread,NULL)!=0) 
    { 

     //throw exception 
     printf("Creation of Output thread failed for Script with ID\n"); 
    } 

    //Create execution thread to launch script 
    pthread_t execThread; 
    if (pthread_create(&ExecThread,0,entryExecThread,NULL)!=0) 
    { 

     //Stop output thread 
     pthread_cancel(OpThread); 
     //throw exception 
     printf("Creation of Execution thread failed for Script with ID\n"); 
    } 
} 

test.c的

#include <stdio.h> 
#include "string.h" 
//using namespace std; 

int main() { 
    int i=0; 
    while(i<500) 
    { 
    printf("!!!Hello World!!! \n"); // prints !!!Hello World!!! 
    //extracting header and data from message 
     sleep(5); 
     i++; 
    } 
    return 0; 
} 

回答

0

發送到管道的數據緩衝,所以你並不需要另一個緩衝區。只要有需要,就從管道讀取數據。您可以使用poll函數來測試是否有要讀取的數據。你不需要讀者線程。

另外你也不需要執行線程,因爲無論如何你都是fork

除了您的應用程序幾乎會立即終止,因爲主線程會在發出輔助線程後結束。

要指出的其他事情是,你應該關閉不需要的手柄。 pipe打開2個句柄,fork複製所有打開句柄,dup2複製句柄。你沒有關閉任何。

如果您只是想讀取某個進程的輸出,請使用popen運行它。下面的簡短例子。

主要應用:

int main() 
{ 
    FILE *f = popen("./test", "r"); // open the process 

    /* Your application is busy now, but the process runs and outputs */ 
    sleep(5); 

    /* Now assume you need some data - just read it */ 
    int c; 
    while (0 <= (c = fgetc(f))) putchar(c); 
} 

測試程序:

int main() 
{ 
    int i; 
    for (i = 0; i < 10; i++) { 
     puts("Hello world!"); 
     fflush(stdout); 
     sleep(1); 
    } 
} 

如果此解決方案不適合你的需求,然後寫了什麼問題。

相關問題