2010-08-08 39 views
1

我很努力不斷地讀取被重定向到文件的標準輸出的內容。請幫我解決問題。如何定期讀取標準輸出上的內容重定向到文件描述符使用dup2

我的問題更詳細的是,我有第一個線程中的兩個線程,我必須執行交替文件輸出到標準輸出(即在無限循環中編寫你好世界),並在第二個線程我必須檢索行從標準輸出週期性地輸出行並存儲在緩衝區中。 對於第二個線程的實現,我創建了管道並重定向了標準輸出到這個管道的寫入結束,並試圖不斷地讀取這條管道的內容,但是我沒有得到期待的結果。對於第二個線程 代碼如下:

int redirectPipe[2]; 
//creation of pipe 
pipe(redirectPipe); 
//redirection of pipe 
dup2(redirectPipe[1],STDOUT_FILENO); 
//reading continuously line by line from pipe 
// some code here 

有人可以幫我在編碼如何不斷通過線路從該管道讀取行?

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

//*************************CODE*********************************************************** 
#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"); 
    } 
} 
//**********************************************************************************888 
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

你是分叉還是使用pthreads? – strager 2010-08-08 10:49:11

+0

是的,我在第一個線程中使用pthread和fork子進程到 運行c文件 – James 2010-08-08 11:15:21

+1

您可以發佈您用來設置線程/進程的代碼嗎? 從描述中很難判斷你正在做什麼,但是如果你fork了,那麼子進程會獲得父文件描述符的一個*副本,所以在fork之後從另一個進程調用dup2將沒有任何效果。 – SimonJ 2010-08-08 11:57:21

回答

0

難道是一個緩衝的問題(http://www.pixelbeat.org/programming/stdio_buffering/)?

當stdout連接到終端時,其輸出將被行緩衝。如果不是這種情況,則輸出是頁面緩衝的。

要驗證,您可以嘗試從寫入程序線程中刪除sleep(),並檢查消費者線程上的輸出(每隔5秒打印少量字節將需要一段時間來填充頁面)。從那裏你可以考慮使用fflush()setvbuf()

相關問題