引擎版本:3.13.1
###资源预加载场景中,异步加载obbfile中的资源闪退,目前已经定位到原因:(多线程访问竞争资源)
- 线程1开始读取battleUI.png;
- 线程2开始读取zd_diaoxue.png,但此时线程1并未执行结束;
- 竞争资源被修改,导致读取中断,触发断言,程序中断
如下图所示:(打印了多线程执行的顺序)
###罗列相关的代码段:
代码1:CCFileUtils-android.cpp
if (obbfile)
{
if (obbfile->getFileData(relativePath, buffer))
return FileUtils::Status::OK;
}
代码2:ZipUtils.cpp
bool ZipFile::getFileData(const std::string &fileName, ResizableBuffer* buffer)
{
bool res = false;
do
{
CC_BREAK_IF(!_data->zipFile);
CC_BREAK_IF(fileName.empty());
CCLOG("Enter thread: %d, fileName: %s", std::this_thread::get_id(), fileName.c_str());
ZipFilePrivate::FileListContainer::const_iterator it = _data->fileList.find(fileName);
CC_BREAK_IF(it == _data->fileList.end());
ZipEntryInfo fileInfo = it->second;
int nRet = unzGoToFilePos(_data->zipFile, &fileInfo.pos);
CC_BREAK_IF(UNZ_OK != nRet);
nRet = unzOpenCurrentFile(_data->zipFile);
CC_BREAK_IF(UNZ_OK != nRet);
CCLOG("Enter thread: %d, fileName: %s, fileInfo.uncompressed_size: %d", std::this_thread::get_id(), fileName.c_str(), (int)fileInfo.uncompressed_size);
buffer->resize(fileInfo.uncompressed_size);
int CC_UNUSED nSize = unzReadCurrentFile(_data->zipFile, buffer->buffer(), static_cast<unsigned int>(fileInfo.uncompressed_size));
CCLOG("Enter thread: %d, fileName: %s, nSize: %d", std::this_thread::get_id(), fileName.c_str(), (int)nSize);
CCLOG("Leave thread: %d, fileName: %s", std::this_thread::get_id(), fileName.c_str());
CCASSERT(nSize == 0 || nSize == (int)fileInfo.uncompressed_size, "the file size is wrong");
unzCloseCurrentFile(_data->zipFile);
res = true;
} while (0);
return res;
}