boost :: uuids :: random_generator和多线程的唯一性

时间:2011-06-01 16:47:44

标签: c++ boost thread-safety boost-uuid

当我使用单线程生成随机数时,4M uuids中没有重复生成但是如果我生成两个线程,每个1M,我看到大约16-20个重复。可能是什么原因?

class TestUuid 
{
 public:
  std::string GenerateUUid(){
       boost::uuids::uuid uid;
       {
          boost::mutex::scoped_lock(m_mRandomGen);
          uid = m_oRandomGen();
       }
       std::stringstream ss;
       ss << uid;
       return ss.str();
  }


  void TestUid(std::map<std::string, unsigned>& mUids, unsigned count){  
    for(unsigned i = 0; i < count; ++i) {
        std::string sUid = GenerateUUid();
        std::map<std::string, unsigned>::const_iterator it = mUids.find(sUid);           
        if(it == mUids.end()){
           mUids[sUid] = i;
        }else {
         std::cerr << "Duplicate uid:" << sUid << " found in  thread id:" << pthread_self() << ", counter:" << i << ", earlier counter:" << it->second << ", id:" << it->first<< std::endl;
        }
    } 
  }

   TestUnique() {
     unsigned count = 4000000;
     std::map<std::string, unsigned> uuids;
     TestUid(uuids, count);
   }

   TestUniqueMultiThread() {
    unsigned count = 1000000;
    std::map<std::string, unsigned> mUids1;
    boost::thread t1(boost::bind(&TestUuid::TestUid, this, mUids1, count));

    std::map<std::string, > Uunsignedids2;
    boost::thread t2(boost::bind(&TestUuid::TestUid, this,  mUids2, count));
    t1.join();
    t2.join();
   }

 private:
   boost::mutex m_mRandonGen;
   boost::uuids::random_generator m_oRandomGen;

}

int main() {
 TestUid oTest;
 oTest.TestUnique();  //work fine. no duplicate in 4M uuids
 oTest.TestUniqueMultiThread(); // around 16-20 duplicates in total 2*1M = 2M uuids
 return EXIT_SUCCESS;
}

下面是日志。

Duplicate uid:9f4bfa5c-8e41-4012-ba3e-0b3e631834dc found in  thread id:1103669568, counter:12016, earlier counter:12015, id:9f4bfa5c-8e41-4012-ba3e-0b3e631834dc
Duplicate uid:0237b010-cb8f-4b89-9f47-042722902883 found in  thread id:1103669568, counter:65778, earlier counter:65777, id:0237b010-cb8f-4b89-9f47-042722902883
Duplicate uid:7a999ce7-0936-4642-b796-485334fc6ba4 found in  thread id:1093179712, counter:170570, earlier counter:170568, id:7a999ce7-0936-4642-b796-485334fc6ba4
Duplicate uid:09e1028b-5fc9-4fcd-ab70-991c02d47aec found in  thread id:1093179712, counter:208740, earlier counter:208739, id:09e1028b-5fc9-4fcd-ab70-991c02d47aec
Duplicate uid:66eb72f5-a3de-4941-8a64-6dad773f0ffb found in  thread id:1093179712, counter:211449, earlier counter:211448, id:66eb72f5-a3de-4941-8a64-6dad773f0ffb
Duplicate uid:8bccb459-1e70-4920-8486-6b0c5dcb3992 found in  thread id:1093179712, counter:212972, earlier counter:212971, id:8bccb459-1e70-4920-8486-6b0c5dcb3992
Duplicate uid:bb8109e3-6529-4122-a015-a9746900f692 found in  thread id:1093179712, counter:239296, earlier counter:239295, id:bb8109e3-6529-4122-a015-a9746900f692
Duplicate uid:a02ea282-b49b-4e4f-98a3-01406824c888 found in  thread id:1103669568, counter:338582, earlier counter:338581, id:a02ea282-b49b-4e4f-98a3-01406824c888
Duplicate uid:8bc848d7-bbe9-405c-9ef3-4d5ec312aa5e found in  thread id:1093179712, counter:472035, earlier counter:472010, id:8bc848d7-bbe9-405c-9ef3-4d5ec312aa5e
Duplicate uid:d3d8e09f-c410-4ce0-9a75-2a0c363db89c found in  thread id:1093179712, counter:531441, earlier counter:531440, id:d3d8e09f-c410-4ce0-9a75-2a0c363db89c
Duplicate uid:3130184f-345e-4d1c-bb01-d481eec29704 found in  thread id:1093179712, counter:548770, earlier counter:548769, id:3130184f-345e-4d1c-bb01-d481eec29704
Duplicate uid:29572641-2487-400a-926f-9bbf7ca176b4 found in  thread id:1093179712, counter:710813, earlier counter:710811, id:29572641-2487-400a-926f-9bbf7ca176b4
Duplicate uid:36b3567d-5f06-4c72-a395-e6f6ce056c6b found in  thread id:1093179712, counter:728598, earlier counter:728597, id:36b3567d-5f06-4c72-a395-e6f6ce056c6b
Duplicate uid:3290cb7e-2535-43bc-b53c-71ac0bc4fca1 found in  thread id:1103669568, counter:846883, earlier counter:846881, id:3290cb7e-2535-43bc-b53c-71ac0bc4fca1
Duplicate uid:59137657-2b2a-473e-b12c-1890d6058ca2 found in  thread id:1093179712, counter:814812, earlier counter:814810, id:59137657-2b2a-473e-b12c-1890d6058ca2

1 个答案:

答案 0 :(得分:12)

使用RAII锁时,这是common error:您忘记在行中为您的锁提供名称

      boost::mutex::scoped_lock(m_mRandomGen);

所以它根本没有锁定任何东西。将其更改为

      boost::mutex::scoped_lock lk(m_mRandonGen); // note the typo in mutex name
编辑:真正发生的事情:尽管互斥锁名称中有拼写错误,但没有编译器错误,因为声明

type(name);

相同
type name;

如果之前没有声明名称。换句话说,您默认构建了一个名为scoped_lock的新m_mRandomGen,与互斥锁无关。