【问题标题】:Can aio_error be used to poll for completion of aio_write?aio_error 可以用来轮询 aio_write 的完成吗?
【发布时间】:2023-01-31 07:10:19
【问题描述】:

我们有一些代码遵循

aiocb* aiocbptr = new aiocb;
// populate aiocbptr with info for the write
aio_write( aiocbptr );

// Then do this periodically:
if(aio_error( aiocbptr ) == 0) {
    delete aiocbptr;
}

aio_error 意味着在写入完成时返回 0,因此我们假设此时我们可以在 aiocbptr 上调用 delete。

这在大多数情况下似乎工作正常,但我们最近开始遇到随机崩溃。证据表明 aiocbptr 指向的数据在调用 delete 后被修改。

像这样使用 aio_error 来轮询 aio_write 完成是否有任何问题?是否保证aio_error 返回0 后aiocb 不会被修改?

This change 似乎表明某些东西可能已经用 aio_error 修复了。我们正在使用 glibc v 2.17 的 x86 RHEL7 linux 上运行,该版本早于此修复程序。

除了 aio_error,我们还尝试使用 aio_suspend,所以一旦 aio_error 返回 0,我们调用 aio_suspend,这意味着等待操作完成。但操作应该已经完成​​,所以 aio_suspend 应该什么都不做。但是,它似乎解决了崩溃问题。

【问题讨论】:

  • 忙碌的等待破坏了使用 aio 的全部意义......
  • 更新它更像我们所做的 - 偶尔轮询 aio_error
  • 来自pubs.opengroup.org/onlinepubs/9699919799The aiocb structure and the data buffers associated with the asynchronous I/O operation are being used by the system for asynchronous I/O while, and only while, the error status of the asynchronous operation is equal to [EINPROGRESS]。你的代码是正确的。回答Can aio_error be used to poll...?是的,这就是它的用途。愚蠢的想法,尝试在调用delete之前添加aio_returnaio_cancel
  • 好吧,正如我所说,在调用 delete 之前添加 aio_suspend 可以修复它,因此调用 aio_return 或 aio_cancel 也可能会修复它。查看对 aio_error 的修复,似乎在旧版本的 libc 中可能存在内存排序竞争错误。

标签: linux posix glibc aio


【解决方案1】:

是的,我的承诺是修复一个缺失的内存屏障。使用例如aio_suspend 触发内存屏障并因此修复它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多