我的代码在本机 Linux 系统上运行得很好,但是当我在 WSL 上运行它时,似乎出了问题。
这是我发送 AsyncWrites 的方式:
Status PosixAIOEngine::AsyncWrite(int fd, uint64_t offset, const char* buffer, uint64_t size,
char** cb) {
if (requests_.size() >= io_depth_) {
LOG(ERROR, "io depth full, please try again later, cur: {}", io_depth_);
return Status::Busy();
}
requests_.push_back({.aio_req_ = {}, .type_ = kAsyncWrite});
auto& request = requests_.back();
memset(&request.aio_req_, 0, sizeof(struct aiocb));
request.aio_req_.aio_offset = (off_t)offset;
request.aio_req_.aio_buf = (void*)buffer;
request.aio_req_.aio_nbytes = size;
request.aio_req_.aio_fildes = fd;
int ret = aio_write(&request.aio_req_);
if (ret == -1) {
auto msg = "aio_write failed, err msg: " + std::string(strerror(errno));
LOG(ERROR, msg);
requests_.pop_back();
return Status::IOError(msg);
}
return Status::OK();
}
发出几个写请求后,我在这里轮询结果:
uint32_t PosixAIOEngine::Poll() {
uint32_t cnt = 0;
auto it = requests_.begin();
while (it != requests_.end()) {
auto& req = *it;
int err_value = aio_error(&req.aio_req_);
// If the request was canceld, we remove & skip it.
if (err_value == ECANCELED) {
it = requests_.erase(it);
continue;
}
// If the request is not yet completed, we skip it.
if (err_value == EINPROGRESS) {
++it;
continue;
}
// If the request has an error.
if (err_value != 0) { <------------------- ERROR here <<<<<<<<<<<<<<<<<<
LOG(ERROR, "I/O failed, aio_error: {}, errmsg: {}, offset: {}", err_value, strerror(errno),
req.aio_req_.aio_offset);
it = requests_.erase(it);
continue;
}
// If there's no operation error occurs, we should check the return value.
int ret_value = aio_return(&req.aio_req_);
if (ret_value == -1) {
LOG(ERROR, "I/O failed, aio_return: {}, errmsg: {}, offset: {}", ret_value, strerror(errno),
req.aio_req_.aio_offset);
it = requests_.erase(it);
continue;
}
// Otherwise, the operation success
it = requests_.erase(it);
cnt++;
}
我首先检查
aio_error
以确保请求已正确发送出去,但它的返回值是38,这意味着Not Implemented
。我想errno也会改变,但结果errno仍然是0,这意味着成功。
问题:
根据这个API的描述:,好像errno的值应该是一样的吧?或者我误解了描述...(不是母语人士)
A positive error number, if the asynchronous I/O operation
failed. This is the same value that would have been
stored in the errno variable in the case of a synchronous
read(2), write(2), fsync(2), or fdatasync(2) call.
好的,解决方案在这里:
事实证明,WSL1.0 无法正确处理异步
aio
(在aio.h
下),所以我将其升级到 WSL2.0,完美运行。