【问题标题】:Calls to ReadFile return ERROR_WORKING_SET_QUOTA调用 ReadFile 返回 ERROR_WORKING_SET_QUOTA
【发布时间】:2010-08-09 17:06:40
【问题描述】:

程序正常运行了几分钟,然后 ReadFile 开始失败,错误代码为 ERROR_WORKING_SET_QUOTA。

我正在使用带有重叠 I/O 的 ReadFile,如下所示:

while (continueReading)
{
    BOOL bSuccess = ReadFile(deviceHandle, pReadBuf, length, 
                             &bytesRead, readOverlappedPtr);
    waitVal = WaitForMultipleObjects(
                (sizeof(eventsToWaitFor)/sizeof(eventsToWaitFor[0])), 
                eventsToWaitFor, FALSE, INFINITE);
    if (waitVal == WAIT_OBJECT_0) {
       // do stuff
    } else if (waitVal == WAIT_OBJECT_0 + 1) {
       // do stuff
    } else if (waitVal == WAIT_OBJECT_0 + 2) {
       // complete the read
       bSuccess = GetOverlappedResult(deviceHandle, &readOverlapped, 
                                      &bytesRead, FALSE);
       if (!bSuccess) {
          errorCode = GetLastError();
          printf("ReadFile error=%d\n", errorCode);
       }
    }
}

为什么会出现这个错误?

【问题讨论】:

    标签: winapi readfile overlapped-io


    【解决方案1】:

    问题是ReadFile 被调用的次数比GetOverlappedResult 多。导致进程耗尽资源来处理所有未完成的读取。

    另外,我们应该检查ReadFile的结果,并确保结果是ERROR_IO_PENDING,如果不是并且ReadFile返回FALSE,那么还有另一个问题。

    确保每次成功调用ReadFile 都会调用一次GetOverlappedResult。像这样:

    BOOL bPerformRead = TRUE;
    while (continueReading) 
    { 
        BOOL bSuccess = TRUE;
        // only perform the read if the last one has finished
        if (bPerformRead) {
           bSuccess = ReadFile(deviceHandle, pReadBuf, length,
                               &bytesRead, readOverlappedPtr);
           if (!bSuccess) {
              errorCode = GetLastError();
              if (errorCode != ERROR_IO_PENDING) {
                 printf("ReadFile error=%d\n", errorCode); 
                 return;
              }
           } else {
              // read completed right away
              continue;
           }
           // we can't perform another read until this one finishes
           bPerformRead = FALSE;
        }
        waitVal = WaitForMultipleObjects( 
                    (sizeof(eventsToWaitFor)/sizeof(eventsToWaitFor[0])),  
                    eventsToWaitFor, FALSE, INFINITE); 
        if (waitVal == WAIT_OBJECT_0) { 
           // do stuff 
        } else if (waitVal == WAIT_OBJECT_0 + 1) { 
           // do stuff 
        } else if (waitVal == WAIT_OBJECT_0 + 2) { 
           // complete the read 
           bSuccess = GetOverlappedResult(deviceHandle, &readOverlapped,  
                                          &bytesRead, FALSE); 
           // the read is finished, we can read again
           bPerformRead = TRUE;
           if (!bSuccess) { 
              errorCode = GetLastError(); 
              printf("GetOverlappedResult from ReadFile error=%d\n", errorCode); 
           } 
        } 
    }
    

    【讨论】:

    • 更接近。但实际上验证 ReadFile 返回 FALSE 和 GetLastError() 返回 ERROR_IO_PENDING 是非常重要的。当数据从文件系统缓存中出来时,读取文件通常会立即完成。
    猜你喜欢
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多