c++ - C++ 中的异步文件 I/O

标签 c++ windows multithreading io

我找不到有关C++异步读写的信息。所以我编写代码,函数 read() 工作正常,但同步不行。 Sync() 函数不等待读取结束。 我认为线程中的变量 state_read 的值不正确。请理解我为什么。

struct IOParams{
    char* buf;
    unsigned int nBytesForRead;
    FILE* fp;
}; 

struct AsyncFile {
     FILE* fp;
     bool state_read;
     HANDLE hThreadRead;
     IOParams read_params;

     void AsyncFile::read(char* buf, unsigned int nBytesForRead){
       sync();
       read_params.buf = buf;
       read_params.fp = fp;
       read_params.nBytesForRead = nBytesForRead;
       hThreadRead = CreateThread(0,0,ThreadFileRead,this,0);
     }

     void AsyncFile::sync() {    
       if (state_read) {
           WaitForSingleObject(hThreadRead,INFINITE);
             CloseHandle(hThreadRead);    
       }
       state_read = false;
    }
};


DWORD WINAPI ThreadFileRead(void* lpParameter) {    
    AsyncFile* asf = (AsyncFile*)lpParameter;
    asf->setReadState(true);
    IOParams & read_params = *asf->getReadParams();
    fread(read_params.buf, 1, read_params.nBytesForRead, read_params.fp);
    asf->setReadState(false);
    return 0;
}

也许你知道如何以更合理的方式编写异步读取。

最佳答案

Maybe you know how to write the asynchronous reading in more reasonable way.

由于您的问题被标记为“Windows”,您可能会研究 FILE_FLAG_OVERLAPPEDReadFileEx,它们无需额外线程即可进行异步读取(通过事件、回调进行同步,或完成端口)。

如果您坚持使用单独的加载器线程(可能有充分的理由,尽管很少),您不希望从两个线程重复读取和写入标志并将其用于同步。尽管您的代码看起来是正确的,但仅不能按预期工作这一事实就表明这是一个坏主意。
始终使用正确同步原语(事件或信号量)进行同步,不要篡改从不同线程写入和读取(可能不一致)的某些标志。 或者,如果您不需要额外的事件对象,您可以始终无条件地等待线程终止(但是,请阅读下一段)。

一般来说,生成一个线程并让它在每次读取时死亡并不是一个好的设计。生成线程不仅会产生相当大的开销(对于 CPU 和内存而言),而且还会引入难以预测的“有趣效果”,并最终导致完全反优化。想象一下,例如,有 50 个线程在搜索时对硬盘驱动器进行攻击,所有线程都试图获取其中的一部分。这肯定是异步的,但也会慢一百倍。
如果您不想使用操作系统的 native 异步机制,那么使用少量工作人员(强调)可能是一个更优越的设计。

关于c++ - C++ 中的异步文件 I/O,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7553640/

相关文章:

C++11 static assert for equality comparable type?

c++ - 奇怪的食人魔错误和一个不存在的文件

c - 消息队列中的多条消息

iOS : Background Thread Exceptions Not Crashing

c++ - 将任何字符串转换为固定大小的字符串

c++ - 可变参数模板类参数容器实例化

c++ - 如何为 IE 编译和构建这个 BHO?

ruby - Ansicon 不适用于 Windows 8

windows - 静态链接 SQLite 与 DMD (Windows x86)

android - 杀死线程中的 Activity