【问题标题】:EFAULT or EDESTADDRREQ for multiple dispatch_io_writes in GCD queueEFAULT 或 EDESTADDRREQ 用于 GCD 队列中的多个 dispatch_io_writes
【发布时间】:2013-01-05 12:12:17
【问题描述】:

我正在尝试实现文件存储队列子系统,如 wwdc 2012 Asynchronous Design Patterns with Blocks、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. 在这种情况下,我应该注意哪些频道标志?

【问题讨论】:

    标签: ios posix grand-central-dispatch


    【解决方案1】:

    如果使用 DISPATCH_IO_STREAM 标志创建不支持随机访问的基于流的通道,则任何偏移值 (currentOffset) 都将被忽略,并且数据将写入当前文件位置(sn-p 中的 0),如所述this.

    【讨论】:

      【解决方案2】:

      我在您的 sn-p 中没有发现任何明显错误。应该不需要手动分块数据并提交多个写入操作(dispatch IO 已经在内部更有效地执行此操作),而且我之前从未听说过遇到这些特定的 IO 错误。

      请提交bug report 并附上重现问题的可运行测试用例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-11
        • 2015-06-08
        • 1970-01-01
        • 2012-12-17
        • 1970-01-01
        • 1970-01-01
        • 2012-09-26
        相关资源
        最近更新 更多