如果有多个进程同时对一个mdb(其它的没看,不敢随便乱说)执行list操作,结果会怎样; 或许你会显得当然地认为相互没有太大关系,至少我开始时这么认为的,但是在看源码的时候,发现有些不太对劲儿,我们先看一下源码:
tcutil.c
- /* Initialize the iterator of an on-memory hash database. */
- void tcmdbiterinit(TCMDB *mdb){
- assert(mdb);
- if(pthread_mutex_lock(mdb->imtx) != 0) return;
- for(int i = 0; i < TCMDBMNUM; i++){
- tcmapiterinit(mdb->maps);
- }
- mdb->iter = 0;
- pthread_mutex_unlock(mdb->imtx);
- }
说明:
1. 在操作mdb的时候,需要给这个mdb加锁,显然这个mdb是一个全局的对象,而不是当前线程私有的,如果另有一个list请求,显然还是用同一个mdb对象,list时使用到了mdb的iter属性;由此看来,多个list请求应该是相互干扰的。下面做一个测试
1. 初始化一个mdb,不需要太多记录,假设200条记录吧
2. 先启动一个list进程,每取出一条记录sleep 100ms;
3. 1s后启动另一个list进程(前一个进程还没有list完成)
4. 这时,我们会发现进程1又重新获取了已经获取的记录,但不是全部,因为有部分被进程2读取了
下面是第一个进程或取的部分key:value
a4:a
a13:a
a22:a
a31:a
a39:a
a40:a
a48:a
a57:a
a66:a
a75:a
a13:a
a31:a
a40:a
a57:a
a75:a
a93:a
a112:a
a129:a
a138:a
a156:a
我们发现a13读取了两次; 第二次没有读取到a22, 是被第二个进程读取走了,然后就直接读取到了a31
————————
还有一个问题,我写入的时候是挨个按照顺序写入的,为什么list的时候有漏洞呢?或许你还发现一点,至少在一段内是从小到大的。
说明:
写入的时候,是按照不同的hash值写入到了8个map中的,而list的时候,是通过for循环8个map来list的,明白了?哦,好吧,that’s over。
tt的遍历时获取的条目数的计数器会记录到cnt_get 上面的。