我无法在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;
}
也许您知道如何以更合理的方式编写异步读取。
答案 0 :(得分:2)
也许您知道如何以更合理的方式编写异步读取。
由于您的问题被标记为“Windows”,因此您可能会查看FILE_FLAG_OVERLAPPED
和ReadFileEx
,它们在没有额外线程的情况下进行异步读取(通过事件,回调或完成端口进行同步)。
如果你坚持使用一个单独的加载器线程(可能有正当理由,尽管很少),你不希望从两个线程重复读取和写入一个标志,并将其用于同步。虽然您的代码看起来正确,但仅仅是预期不能正常工作的事实表明这是一个坏主意。
始终使用正确的同步原语(事件或信号量)进行同步,不要篡改某些(可能不一致)写入和从不同线程读取的标志。
或者,如果你不想要一个额外的事件对象,你可以总是等待线程无条件地死掉(但是,阅读下一段)。
通常,产生一个线程并让它在每次读取时死亡都不是一个好的设计。不仅产生一个线程相当大的开销(包括CPU和内存),它还可以引入难以预测的“有趣效果”,并且结果是完全反优化。想象一下,例如有50个线程在寻找硬盘时捶打,所有这些都试图获得一点点。这肯定是异步的,但它也会慢一百倍 如果您不想使用操作系统的本机异步机制,那么使用一小部分工作者(强调 small )可能是一个非常优秀的设计。