2

ノンブロッキングパイプについてはたくさんの質問がありますが、コピーアンドペースト(ほとんど修正なし)して使用できるコードの例はありません。

私はこのスレッドからアイデアと情報源を得ました: popenを使用したノンブロッキングパイプ?

しかし、それをどのように使用するのですか?whileサイクルで?変更内容を確認してください。本当にerrno == EAGAIN&追加のヘッダーを使用する必要があり#include <cerrno>ますか?必要に応じて、より良いバージョンを所有することを提案します。

    FILE *pipe;
    char buff[512];
    if ( !(pipe = popen( command.c_str(), "r")) ) return false;

    int d = fileno(pipe);   
    while ( true )
    {
        ssize_t r = read(d, buff, sizeof(buff));
        if (r == -1 && errno == EAGAIN) // really need errno? 
            continue;
        else if (r > 0)
            ptr_output->append(buff);       
        else
            break;
    }

    pclose(pipe);
4

2 に答える 2

1

はい。read呼び出しがエラー値(-1 errno返され、に設定されている場合EAGAIN、それはデータが利用できないことを意味するためcontinue、ループして再試行します。をerrno削除すると、エラーは事実上無視され、プログラムがクラッシュする可能性があります。あなたがそれを取り除いたと想像してみてください:read戻ったとき-1、しかし、例えば、パイプが壊れていた(もう一方の端がそれを閉じた)というエラーは、あなたはただループして無限ループに入ろうとし続けるでしょう。悪いアイデア。

于 2012-06-09T15:15:52.563 に答える
0

私のLinuxマルチスレッドアプリケーション(Ubuntu 16.04、x86_64、ネイティブPOSIXスレッド、libc.so.6バージョンUbuntu GLIBC 2.23-0ubuntu9)では、 このコード

int fd = fileno(pipe);
fcntl(fd, F_SETFL, O_NONBLOCK);
while (true)
        {
            ssize_t r = read(fd, buff, sizeof(buff));
            if ((r == -1) && (errno == EAGAIN)) // really need errno?
                continue;
            else
            {
                if (r > 0)
                    result += buff;
                else
                    break;
            }
        }

fctnl(...)コマンドの出力だけでなく、RAMから他の多くの任意の値が読み取られることが多いため、原因があっても失敗します。コードのスレッドの安全性が低いことが原因だと思います。

(例:10、30、40のecho3つの値を、20スレッドずつ並列にread実行し、最後の値のみを表示します。出力:40 QIh MIh 40 40 30 ...)

この回答の別のコードfgetsは、実装がスレッドセーフであるため正常に機能します。

while (!feof(pipe))
{
    if (fgets(buff, sizeof(buff), pipe) != NULL)
    result += buff;
}
于 2017-08-26T18:41:07.007 に答える