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 驱动程序之上,该驱动程序调用 socket(7) 子系统,该子系统设置 errno。特别是,C 驱动程序库进行非阻塞套接字 IO 调用,这解释了您在 errno 中观察到的 EWOULDBLOCK/EAGAIN 值。

通常,使用 errno 的良好做法要求您在调用要为其提取详细错误信息的函数后立即捕获 errno 值。干预电话可能会重置它。

于 2015-09-16T19:15:53.993 回答