6

我正在尝试使用 ifstream 打开一个命名管道,该管道最终将写入数据。

std::cout << "Opening " << name << std::endl;
std::ifstream manual_shutdown_file(name.c_str());
std::cout << "Opened " << name << std::endl;

当我运行程序时,它会阻塞在ifstream构造函数中。我看到控制台打印了“Opening name”,但没有出现打开的语句。

我知道我正在连接到管道,因为如果我执行

$ echo foo > name

从 shell 中,然后构造函数返回并打印 Opened 语句。即使我不想立即尝试读取它,在管道中包含数据之前是否无法打开管道?

4

3 回答 3

2

调用open管道的读取端将阻塞,直到打开写入端。

您可以使用该O_NONBLOCK标志打开管道的文件描述符,但没有标准方法可以使用 fd std::ifstream请参见此处。

根据您的要求猜测,我会说一个打开 fd 并提供轮询信号接口的小类将适合,例如:

namespace blah
{
class signal_t
{
private:
   int fd;

   // note: define sensible copy/move semantics
   signal_t(const signal_t&) = delete;
   signal_t& operator=(const signal_t&) = delete;
public:
   signal_t(const char* named_pipe);   // open fd, set O_NONBLOCK

   void notify() const;                // write 1 byte to fd as signal
   bool poll() const;                  // attempt to read from fd, return true if signalled.

   ~signal_t();                        // close fd
};
}
于 2013-03-05T00:35:09.213 回答
0

由于通过块打开输入管道ifstream直到有人写信,你总是可以让ifstream块。然后从另一个线程解除阻塞,创建你自己的ofstream到同一个管道,然后立即关闭ofstream. 这将解除阻止ifstream并用 标记它eof。与弄乱文件句柄的平台特定控件相比,这更容易且更不容易出错。

于 2020-08-06T01:27:37.510 回答
-1

实际上,您可以std::ifstream在命名管道上打开 a 而不会阻塞写入器,但是您必须设置标志,就好像您也要写入流一样。

尝试std::ifstream pipe_stream(filename, std::ifstream::in | std::ifstream::out),或stream.open(filename, std::ifstream::in | std::ifstream::out)

于 2016-03-10T23:58:03.213 回答