2016-06-02 21 views
1

Ich schreibe einen C++ SNMP-Server mit einer NET-SNMP-Bibliothek. Ich lese die documentation und habe immer noch eine Frage. Können mehrere Threads eine einzelne SNMP-Sitzung teilen und sie gleichzeitig in Prozeduren wie snmp_sess_synch_response() verwenden, oder muss ich eine neue Sitzung in jedem Thread initiieren und öffnen?NET-SNMP und Multithreading

Antwort

0

Nun, wenn ich versuche, snmp_sess_synch_response() aus zwei verschiedenen Threads mit der gleichen Opak Sitzung Zeiger gleichzeitig, einer der drei Fehler immer auftritt. Die erste ist eine Speicherzugriffsverletzung, die zweite ist endlos WaitForSingleObject() in beiden Threads und die dritte ist Heap-Allocation-Fehler.

Ich nehme an, dass ich dies als eine Antwort behandeln kann, also einzelne Sitzung zwischen mehreren Threads teilen ist unsicher, weil die Verwendung in Prozeduren wie snmp_sess_synch_response() gleichzeitig einen Fehler verursacht.

P.S. Hier ist das Stück Code von zuvor beschrieben:

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; 
}