NET-SNMP 和多线程

NET-SNMP and multithreading

我正在使用 NET-SNMP 库编写 C++ SNMP 服务器。我阅读了 documentation,但仍有一个问题。多个线程能否共享单个 snmp 会话并同时在 snmp_sess_synch_response() 等过程中使用它,或者我必须在每个线程中初始化并打开新会话?

好吧,当我试图从两个不同的线程snmp_sess_synch_response() 同时使用相同的不透明会话指针时,总是会出现三个错误之一。第一个是内存访问冲突,第二个是无限的 WaitForSingleObject() 在两个线程中,第三个是堆分配错误。

我想我可以把它当作一个答案,因此在多个线程之间共享单个会话是不安全的,因为在 snmp_sess_synch_response() 这样的过程中同时使用它会导致错误。

P.S。这是之前描述的一段代码:

void* _opaqueSession;
boost::mutex _sessionMtx;

std::shared_ptr<netsnmp_pdu> ReadObjectValue(Oid& objectID)
{
    netsnmp_pdu*    requestPdu = snmp_pdu_create(SNMP_MSG_GET);
    netsnmp_pdu*    response = 0;
    snmp_add_null_var(requestPdu, objectID.GetObjId(), objectID.GetLen());

    void* opaqueSessionCopy;
    {
        //Locks the _opaqueSession, wherever it appears
        boost::mutex::scoped_lock lock(_sessionMtx);
        opaqueSessionCopy = _opaqueSession;
    }

    //Errors here!
    snmp_sess_synch_response(opaqueSessionCopy, requestPdu, &response);

    std::shared_ptr<netsnmp_pdu> result(response);
    return result;
}

void ExecuteThread1()
{
    Oid sysName(".1.3.6.1.2.1.1.5.0");
    try
    {
        while(true)
        {
            boost::thread::interruption_pont();
            ReadObjectValue(sysName);
        }
    }
    catch(...)
    {}
}

void ExecuteThread2()
{
    Oid sysServices(".1.3.6.1.2.1.1.7.0");
    try
    {
        while(true)
        {
            boost::thread::interruption_pont();
            ReadObjectValue(sysServices);
        }
    }
    catch(...)
    {}
}

int main()
{
    std::string community = "public";
    std::string ipAddress = "127.0.0.1";
    snmp_session    session;
    {
        SNMP::snmp_sess_init(&session);

        session.timeout = 500000;
        session.retries = 0;

        session.version = SNMP_VERSION_2c;
        session.remote_port = 161;

        session.peername = (char*)ipAddress.c_str();

        session.community = (u_char*)community.c_str();
        session.community_len = community.size();
    }

    _opaqueSession = snmp_sess_open(&session);

    boost::thread thread1 = boost::thread(&ExecuteThread1);
    boost::thread thread2 = boost::thread(&ExecuteThread2);

    boost::this_thread::sleep(boost::posix_time::seconds::seconds(30));

    thread1.interrupt();
    thread1.join();

    thread2.interrupt();
    thread2.join();

    return 0;
}