提高:: ::的UUID和random_generator独特多线程 [英] boost::uuids::random_generator and uniqueness with multiple threads

查看:574
本文介绍了提高:: ::的UUID和random_generator独特多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 类TestUuid
{
 上市:
  标准::字符串GenerateUUid(){
       提高:: UUID的UUID :: UID;
       {
          提高::互斥:: scoped_lock中(m_mRandomGen);
          UID = m_oRandomGen();
       }
       的std :: stringstream的SS;
       SS<< UID;
       返回ss.str();
  }
  无效TestUid(性病::地图<的std ::字符串,无符号>&安培; mUids,无符号数){
    对(无符号I = 0; I<计数; ++ I){
        标准::字符串SUID = GenerateUUid();
        性病::地图<的std ::字符串,无符号> ::为const_iterator吧= mUids.find(SUID);
        如果(它== mUids.end()){
           mUids [SUID] =我;
        }其他{
         的std :: CERR<< 重复UID:<< SUID<< 在线程ID找到:<< pthread_self()&所述;&下; 柜台:<< I<< 前面柜台:<< IT->第二个<< ID:<<它 - >首先<<的std :: ENDL;
        }
    }
  }   TestUnique(){
     无符号数= 4000000;
     性病::地图<的std ::字符串,无符号>的UUID;
     TestUid(的UUID,计数);
   }   TestUniqueMultiThread(){
    无符号数= 1000000;
    性病::地图<的std ::字符串,无符号> mUids1;
    提高::线程T1(的boost ::绑定(安培; TestUuid :: TestUid,为此,mUids1,计数));    性病::地图<的std ::字符串> Uunsignedids2;
    提高::线程T2(的boost ::绑定(安培; TestUuid :: TestUid,为此,mUids2,计数));
    t1.join();
    t2.join();
   } 私人的:
   提高::互斥m_mRandonGen;
   提高:: UUID的:: random_generator m_oRandomGen;}诠释主(){
 TestUid oTest;
 oTest.TestUnique(); //做工精细。在4M的UUID没有重复
 oTest.TestUniqueMultiThread(); // 16-20左右重复,共有2 * 1M = 2M的UUID
 返回EXIT_SUCCESS;
}

下面是日志。


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


解决方案

这是一个<一个href=\"http://stackoverflow.com/questions/5158990/concerning-raii-how-to-$p$pvent-errors-caused-by-accidentally-creating-a-temporar\">common <一href=\"http://stackoverflow.com/questions/914861/disallowing-creation-of-the-temporary-objects\">error使用RAII锁时:你忘了给你的锁的名称的该行

 的boost ::互斥:: scoped_lock中(m_mRandomGen);

所以也没锁的所有东西。将其更改为

 的boost ::互斥:: scoped_lock的LK(m_mRandonGen); //注意互斥名错字

编辑:到底发生了什么:有,尽管互斥名错字没有编译器错误,因为声明

 键入(名);

是相同的

 键入名称;

如果该名称尚未之前声明。换句话说,你已经默认构造一个新的的scoped_lock 名为 m_mRandomGen ,不与互斥有关。

When I generate the random number with single thread, no duplicate in 4M uuids generated but if I generate with two threads each 1M, I see roughly 16-20 duplicates. What could be the reason?

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

below is the log.

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

解决方案

This is a common error when using RAII locks: you forgot to give your lock a name in the line

      boost::mutex::scoped_lock(m_mRandomGen);

so it didn't lock anything at all. Change it to

      boost::mutex::scoped_lock lk(m_mRandonGen); // note the typo in mutex name

EDIT: what really happened: There was no compiler error despite the typo in the mutex name because the declaration

type(name);

is the same as

type name;

if the name has not been declared before. In other words, you've default-constructed a new scoped_lock called m_mRandomGen, not associated with a mutex.

这篇关于提高:: ::的UUID和random_generator独特多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆