【发布时间】: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/9699919799:
The 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_return或aio_cancel。 -
好吧,正如我所说,在调用 delete 之前添加 aio_suspend 可以修复它,因此调用 aio_return 或 aio_cancel 也可能会修复它。查看对 aio_error 的修复,似乎在旧版本的 libc 中可能存在内存排序竞争错误。