6

ifstreamを使用して名前付きパイプを開き、最終的にデータが書き込まれるようにしようとしています。

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

プログラムを実行すると、ifstreamコンストラクターでブロックされます。コンソールに「Openingname」が印刷されていますが、openedステートメントが表示されません。

パイプに接続していることを知っています。

$ echo foo > name

シェルから、コンストラクターが戻り、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実際には、ライターをブロックせずに名前付きパイプでを開くことができますが、ストリームに書き込む場合と同じようにフラグを設定する必要があります。

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 に答える