EFAULT或EDESTADDRREQ用于GCD队列中的多个dispatch_io_writes

时间:2013-01-22 09:47:26

标签: ios posix grand-central-dispatch

我正在尝试实现文件存储队列子系统,如wwdc 2012带块的异步设计模式,GCD和XPC中所述。我有一个自定义并发处理队列,它格式化数据并将结果移交给我的自定义并发存储队列。然后,存储队列创建一个dispatch_io_t通道进行写入,拆分文件(如果我不拆分文件,我会得到大数据的内存问题),并使用dispatch_io_write写入每个块。有时写入完成没有错误,但我经常为任何一个块获得EFAULTEDESTADDRREQ

我的一般方法概述如下:

dispatch_async(processingQueue, ^{

// prepare dispatch data for storageQueue

dispatch_async(storageQueue, ^{

    dispatch_io_t writeChannel = dispatch_io_create_with_path(DISPATCH_IO_STREAM,
                                                              [pathString UTF8String],
                                                              O_RDWR|O_CREAT, // read-write, create if not exist
                                                              S_IRWXU|S_IRWXG|S_IRWXO, // set all permissions
                                                              storageQueue,
                                                              ^(int error) {

                                                              });

    __block size_t chunkSize = STORAGE_WRITE_CHUNK_SIZE;

    __block off_t currentOffset = 0;

    dispatch_io_set_high_water(writeChannel, chunkSize);

    for (currentOffset = 0; currentOffset < imageDataSize; currentOffset += chunkSize) {

        // is dispatch_barrier required?
        dispatch_data_t blockData = dispatch_data_create_subrange(dictData,
                                                                  currentOffset,
                                                                  MIN(imageDataSize - currentOffset,chunkSize));


        if (dispatch_data_get_size(blockData) > 0) {

            dispatch_io_write(writeChannel,
                              currentOffset,
                              blockData,
                              storageQueue,
                              ^(bool done, dispatch_data_t data, int error){

                              });

        } else {

            NSLog(@"Error chunking data for writing!!");
            break;

        }
    }

    dispatch_io_close(writeChannel,0);
});
});

我尝试使用串行队列,包装dispatch_barrier块,修改dispatch_io channel标志,但问题仍然存在 - dispatch_io_write由于地址或目的地错误导致的频繁错误

想得到一些答案:
1.使用dispatch_io_write和自定义并发队列进行缓冲文件写入的推荐方法是什么? 2.我是否需要使用dispatch_barrier,如果是,dispatch_io_barrier频道或队列的dispatch_barrier_async? 3.在这种情况下,我是否应该注意任何通道标志?

2 个答案:

答案 0 :(得分:0)

我的代码段中没有看到任何明显错误的内容。应该不需要手动分块数据并提交多个写操作(调度IO已经在内部更有效地执行此操作),并且我从未听说过之前遇到的那些特定IO错误。

请使用可再现问题的可运行测试用例提交bug report

答案 1 :(得分:0)

如果使用DISPATCH_IO_STREAM标志创建基于流的通道,不支持随机访问,则忽略任何偏移值(currentOffset),并将数据写入当前文件位置(在您的代码段中为0),如所述{{ 3}}