Впервые пытаюсь работать с файлом в асинхронном режиме. Задача проста - заполнить файл в асинхронном режиме, не дожидаясь заполнения запустить расчет формулы, и выводить время выполнения всех операций. Программа создает на диске C файл test.bin размером 120 мб, создает кусками по 40мб (ибо такие куски, как показали эксперименты, пишутся медленно, а мне нужно проверять именно асинхронную запись, поэтому чем медленнее - тем нагляднее). Код записи Код (Text): bool CFileWork::WriteAsync(char* file_path, BYTE* data, UINT data_size, UINT buffer_size) { file = CreateFile (file_path,GENERIC_WRITE, FILE_SHARE_READ,NULL,OPEN_ALWAYS, FILE_FLAG_OVERLAPPED,NULL); if (file == INVALID_HANDLE_VALUE) return false; events_num = data_size / buffer_size; if((data_size%buffer_size)!= 0) events_num++; events = new HANDLE [events_num]; over = new OVERLAPPED [events_num]; ZeroMemory(events, sizeof(HANDLE)*events_num); ZeroMemory(over, sizeof(OVERLAPPED)*events_num); DWORD written; int i = 0,ev_index=0; timer.StartCount(); for(; i < data_size - buffer_size; i+=buffer_size,ev_index++){ events[ev_index] = CreateEvent (0, true, false, 0); over[ev_index].hEvent = events[ev_index]; over[ev_index].Offset = i; WriteFile (file, data+i, buffer_size, &written, &over[ev_index]); } events[events_num-1] = CreateEvent (0, true, false, 0); over[ev_index].hEvent = events[events_num-1]; over[ev_index].Offset = i; WriteFile (file, data+i, data_size-i, &written, &over[ev_index]); CloseHandle (file); return true; } Вызов всех функций Код (Text): UINT data_size = 480 * 1024 * 1024; UINT buffer_size = 40*1024*1024; data = new BYTE [data_size]; srand (GetTickCount()); for(int i = 0; i < data_size; i++){ data[i] = i%256; } DeleteFile ("c:\\test.bin"); full_timer.StartCount(); filework.WriteData("c:\\test.bin", data, data_size, buffer_size, true); full_timer.StopCount(); std::cout << "writing initialized. time is " << full_timer.GetDelta() << " ms\n"; CreateThread(NULL, 0, ThreadWaitOperation, 0, 0, &tid); calc_timer.StartCount(); DialogBox(GetModuleHandle(0), (LPCSTR)IDD_MAIN, 0, (DLGPROC)About); calc_timer.StopCount(); full_timer.StopCount(); std::cout << "calc time is " << calc_timer.GetDelta() << " ms\n"; std::cout << "full work time is " << full_timer.GetDelta() << " ms\n"; и поток ожидания завершения записи Код (Text): DWORD WINAPI ThreadWaitOperation(LPVOID lpParameter) { filework.WaitOperationFinish(); std::cout << "async write finished. time is " << filework.GetTime() << " ms\n"; return 1; } bool CFileWork::WaitOperationFinish() { DWORD ret; ret = WaitForMultipleObjects(events_num, events, true, INFINITE); timer.StopCount(); ClearEvents(); return true; } У меня выполнение явно не асинхронное: writing initialized. time is 1898.34 ms async write finished. time is 1905.51 ms Должно быть время на инициализацию значительно меньше времени всей записи. Кто нибудь может объяснить, в чем дело?
помоему при закрытии файла все операции записи явно выполняются. попробуй замерить время выполнения в WriteAsync отдельных кусков, помоему на CloseHandle(file) будет как раз фактическая запись...
Ответ на проблему не знаю, но у тебя есть другаю: коррупция стака. 4-ий параметр для WriteFile (пойнтер lpNumberOfBytesWritten) должен оставатся валидным до конца I/O запроса (т.е. даже до полного completion of asynchronous I/O request).
writing initialized. time is 19.4853 ms async write finished. time is 8115.04 ms перенес CloseHandle в часть кода после WaitForMultipleObjects. Как то не очень понятно. Вчера тестил - медленно выполнялась именно WriteFile, управление выходило из него после фактической записи и до CloseHandle управление доходило, када файл полностью записан, как будто венда предвидела, что хэндл клозю сразу после последней записи... comrade в асинхронной записи этот параметр до лампочки, главное не передавать неверный указатель. Но то что стек убьется - заменил на переменную класса, спасибо =)
мля, так и возникает мысль о не нужности поиска, т.к. никто не пишет чем все кончилось. Прихожу к мысли, что мне все-таки нужно создавать свою тему (