1

多くの mongodb c++11 関数がシステム errno コードを 11 (EWOULDBLOCK / EAGAIN) に変更しているようです。これは現在、私のプログラムの残りの部分に干渉しています。いくつか質問があります。

  • mongodb が errno を 11 に変更する理由は何ですか?
  • さまざまな mongodb 関数を呼び出すたびに errno をリセットする必要があることを回避する方法はありますか?

以下は、errno の変化がどれほど広範囲に及ぶかを示す例です。この例は、https ://www.mongodb.com/blog/post/introducing-new-c-driver?jmp=docs&_ga=1.90709144.367237569.1438109079 から改作されています。

#include <iostream>

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>

#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>

int main(int, char**) {
    errno = 0;
    int counter(0);
    std::string str;

    mongocxx::instance inst{};
    mongocxx::client conn{};

    bsoncxx::builder::stream::document document{};

    auto collection = conn["testdb"]["testcollection"];
    document << "hello" << "world";

    printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
    collection.insert_one(document.view());
    printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
    errno = 0;

    printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
    collection.insert_one(document.view());
    printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
    errno = 0;

    auto cursor = collection.find({});

    printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
    for (auto&& doc : cursor) {
        if (errno) {
            printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
            errno = 0;
        }

        str = bsoncxx::to_json(doc);
        //std::cout << str << std::endl;
        printf("counter: %i\n",counter++);
    }

    printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
    collection.drop();
    printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
}

次の出力が得られます。

errno 0 ... hellomongo.cpp:22
errno 11 ... hellomongo.cpp:24
errno 0 ... hellomongo.cpp:27
errno 11 ... hellomongo.cpp:29
errno 0 ... hellomongo.cpp:34
errno 11 ... hellomongo.cpp:37
counter: 0
counter: 1
errno 0 ... hellomongo.cpp:46
errno 11 ... hellomongo.cpp:48
4

1 に答える 1

0

一般に、ほぼすべてのライブラリへのほぼすべての呼び出しで、errno が変更される可能性があると想定する必要があります。

内部的には、C++11 ドライバーは C ドライバーの上に構築され、errno を設定する socket(7) サブシステムを呼び出します。特に、C ドライバ ライブラリはノンブロッキング ソケット IO 呼び出しを行います。これにより、errno で観察されている EWOULDBLOCK/EAGAIN 値が説明されます。

一般に、errno を適切に使用するには、詳細なエラー情報を抽出する関数を呼び出した直後にerrno 値を取得する必要があります。介在する呼び出しは、それをリセットする可能性があります。

于 2015-09-16T19:15:53.993 に答える