2016-06-02 52 views
1

NET-SNMPライブラリを使用してC++ SNMPサーバを作成しています。私はdocumentationを読んでいますが、まだ1つの質問があります。複数のスレッドが1つのsnmpセッションを共有し、snmp_sess_synch_response()のような手順で同時に使用できますか、または各スレッドで新しいセッションを初期化して開く必要がありますか?NET-SNMPとマルチスレッド

答えて

0

同じ不透明なセッションポインタを同時に使用する2つの異なるスレッドからsnmp_sess_synch_response()にしようとすると、3つのエラーのうちの1つが常に発生します。最初はメモリアクセス違反、2番目は無スレッドWaitForSingleObject()であり、3番目はヒープ割り当てエラーです。

私は答えとして扱うことができると思います。つまり、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; 
}