ibireme / YYCache

High performance cache framework for iOS.
MIT License
2.37k stars 505 forks source link

多线程读的时候会crash? #29

Closed yufenglv closed 8 years ago

yufenglv commented 8 years ago

我改了下demo,用并发线程进行读的时候会crash 写的时候sqlite有文件锁,是正常的。

ibireme commented 8 years ago

能写一下使用的版本、相关代码、崩溃日志或崩溃代码位置吗?

yufenglv commented 8 years ago

用的是master的代码 代码截图 crash 截图

yufenglv commented 8 years ago

测试代码

dispatch_queue_t queue = dispatch_queue_create("com.test",  DISPATCH_QUEUE_CONCURRENT);
for(int i = 0; i < 10; ++i){
    dispatch_async(queue, ^{
        NSTimeInterval begin, end, time;
        begin = CACurrentMediaTime();
        @autoreleasepool {
            for (int i = 0; i < 10000; i++) {
                YYKVStorageItem *item = [yykvSQLite getItemForKey:keys[i]];
                NSNumber *value = [NSKeyedUnarchiver unarchiveObjectWithData:item.value];
                if (!value) printf("error!");
            }
        }
        end = CACurrentMediaTime();
        time = end - begin;
        printf("YYKVSQLite:   %8.2f\n", time * 1000);
    });
}
ibireme commented 8 years ago

这个是测试 YYKVStorage 的代码,这个类不是线程安全的,一般也没必要直接用这个类,注释已经给了 warning:https://github.com/ibireme/YYCache/blob/master/YYCache/YYKVStorage.h#L61-L74

需要线程安全的话,用 YYDiskCache,它对 YYKVStorage 进行了封装,提供了足够简单的接口和线程安全的保障。

yufenglv commented 8 years ago

了解了,多谢回答 ~

yufenglv commented 8 years ago

你好,再请教下,看代码dickcache是用信号量来加锁,sqlite的读本身不是支持并发的吗?是因为读的时候要更新accessTime,所以才加锁的吗?

ibireme commented 8 years ago

sqlite 本身只存储一些属性(key/size/filename/accesstime等)和数据量较小的 value,其他大部分数据都是保存成单独的文件的,这部分读写要加锁来避免数据不同步。另外每次访问 sqlite 时,读操作大都会跟着写操作,所以即使支持了读并发也提高不了什么效率吧。

yufenglv commented 8 years ago

恩,多谢 ~