C++ 在没有数据的管道上打开ifstream而不阻塞

C++ 在没有数据的管道上打开ifstream而不阻塞,c++,named-pipes,fstream,ifstream,C++,Named Pipes,Fstream,Ifstream,我正在尝试使用ifstream打开一个命名管道,最终将数据写入其中 std::cout << "Opening " << name << std::endl; std::ifstream manual_shutdown_file(name.c_str()); std::cout << "Opened " << name << std::endl; 从shell中,构造函数返回,并打印打开的语句。即使我不想立即尝试读取管道中

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

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

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

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

您可以使用
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
};
}

实际上,您可以在命名管道上打开
std::ifstream
,而无需为写入程序阻塞,但必须设置标志,就好像您也要写入流一样


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

由于通过
ifstream
打开输入管道直到有人向其写入,您始终可以让
ifstream
阻塞。然后,要从另一个线程中解除阻止,请创建自己的
到同一管道,然后立即关闭
。这将解锁
ifstream
,并将其标记为
eof
。这比使用文件句柄的平台特定控件更容易,而且容易出错。

从3打开“OAXRDWR打开读写。如果这个标志被应用到FIFO上,结果是未定义的。”我猜C++中打开一个文件读写模式也会做同样的事情。
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
};
}