2015-12-08 70 views
1

我有一個管道,可以在分叉程序中的2個進程之間進行通信。它是使用pipe()調用創建的 - http://linux.die.net/man/2/pipe 。一切正常,直到我想執行一些文件操作。分叉,管道和文件操作

此代碼:

pipe.writeBuffer(message.c_str(), message.length()); 
ofstream file; 
file.open(name.c_str(), ios::app); 
file << "stringData"; // put some data to file (many times) 

但是這一次沒有:

ofstream file; 
file.open(name.c_str(), ios::app); 
pipe.writeBuffer(message.c_str(), message.length()); 
file << "stringData"; // put some data to file (many times) 

在第二個例子是沒有的 「文件< < someStream」 的效果 - 我得到空文件。 那有什麼問題?這是文件描述符的問題嗎?管道使用fd [0] - 輸入和fd [1] - 輸出。也許fstream也使用相同的輸出文件處理程序?

這裏是「工作」的樣本: http://pastebin.com/gJ4PbHvy

#include <sys/types.h> 
#include <cstdlib> 
#include <unistd.h> 
#include <iostream> 
#include <fstream> 

#define maxSize 64 

using namespace std; 

class Pipe 
{ 
    public: 
     Pipe() 
     { 
      pipe(fdesc); 
     } 

     ~Pipe() {} 

     void writeBuffer(const char* message, size_t length) 
     { 
      close(fdesc[0]); 
      write(fdesc[1], message, length); 

     } 

     void readBuffer() 
     { 
      char buffer[maxSize]; 
      close(fdesc[1]); 
      size_t result = read(fdesc[0], &buffer, sizeof(buffer)); 
      cout << buffer << endl; 

     } 

    private: 
     int fdesc[2]; 

}; 

class Writer 
{ 
    public: 
     Writer(Pipe &obj) 
     { 
      pipe = obj; 
     } 

     ~Writer() 
     {} 

     void entry() 
     { 
      std::string name = "./myFile"; 
      ofstream file; 
      file.open(name.c_str(), ios::app); 

      std::string message = "hello world"; 
      pipe.writeBuffer(message.c_str(), message.length()+1); 

      if (file.is_open()) 
      { 
       file << "Hello World!" << endl; 
       file.close(); 
      } 
      else 
      { 
       perror("file.is_open()"); 
      } 

      sleep(1); 

     } 

    private: 
     Pipe pipe; 

}; 


class Reader 
{ 
    public: 
     Reader(Pipe &obj) 
     { 
      pipe = obj; 
     } 

     ~Reader() 
     {} 


     void entry() 
     { 
      pipe.readBuffer(); 
      sleep(1); 

     } 

    private: 
     Pipe pipe; 

}; 

int main(int argc, char *argv[]) 
{ 
    Pipe pipe; 
    Reader reader(pipe); 
    Writer writer(pipe); 

    pid_t pid = fork(); 

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

    if (pid == 0) 
    {  
     // child process 
     while(1) 
      reader.entry(); 

    } 
    else 
    { 
     // parent process 
     while(1) 
      writer.entry(); 

    } 

} 
+1

是什麼somestream?什麼是信息?這個問題沒有任何意義。 – SergeyA

+0

你可以考慮這個:file <<「anything」;而在第二個示例中,您將不會在創建的文件中找到「任何東西」。第一個樣本按預期工作。 – neutrino

+0

什麼是'ios :: app'?你確認該文件已成功打開嗎?在檢查文件上下文之前確定文件已關閉嗎?管道和你正在使用的流之間不能有任何連接。 – SergeyA

回答

1

隨着發佈程序,得到一個空文件所描述的問題是不可複製的,因爲在每次運行它寫一行Hello World!myFile,但這仍顯示錯誤,因爲您打算每秒寫一行。原因是close(fdesc[0])writeBuffer():雖然在編寫器進程中關閉管道一次的讀取端是正確的,但每次調用writeBuffer()時都會執行該操作,因爲該文件描述符可以(並且在該情況下)在第一個close()之後重新用於其他文件(這裏是文件ofstream file)之後,該文件在關閉之後而不是(已經關閉的)管道,以便沒有任何東西可以寫入文件。修復:安排你的程序只關閉管道一次, G。通過改變

  close(fdesc[0]); 

  if (0 <= fdesc[0]) close(fdesc[0]), fdesc[0] = -1;