我有一个管道可以在 fork 程序中的两个进程之间进行通信。它是使用 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)
在第二个示例中,“file << 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();
}
}
最佳答案
使用发布的程序,无法重现所描述的获取空文件的问题,因为在每次运行时它都会将一行 Hello World!
写入 myFile
,但这仍然显示错误,因为您打算每秒写一行。原因是 writeBuffer()
中的 close(fdesc[0])
:虽然关闭管道的读取端一次是正确的在 writer 进程中,每次调用 writeBuffer()
时都这样做是不正确的,因为该文件描述符可以(并且在手头的情况下确实)在第一个 之后被重用close()
用于另一个文件(这里是文件 ofstream file
),它是在它关闭之后而不是(已经关闭的)管道,因此无法将任何内容写入文件。修复:安排你的程序只关闭一次管端,e。 G。通过改变
close(fdesc[0]);
到
if (0 <= fdesc[0]) close(fdesc[0]), fdesc[0] = -1;
关于c++ - fork 、管道和文件操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34165004/