Здравствуйте. Пытаюсь проводить запись чтение больших файлов и одновременно выполнять ряд побочных функций используя асинх-ю передачу(fasm, win64): invoke GetProcessHeap invoke HeapAlloc,rax,0,125*1024*1024 mov [pmemory],rax invoke GetLastError invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,rax,0,horhe,100,0 invoke MessageBox,0,horhe,horhe,0 invoke CreateFile,_testfile,GENERIC_READ,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0 mov [hfile],rax invoke GetLastError invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,rax,0,horhe,100,0 invoke MessageBox,0,horhe,horhe,0 invoke ReadFileEx,[hfile],[pmemory],125*1024*1024,lpoverlap,FileIOCompletionRoutine invoke GetLastError invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,rax,0,horhe,100,0 invoke MessageBox,0,horhe,horhe,0 \\\ побочные функции в цикле \\\ proc FileIOCompletionRoutine ErrorCode,ErrorCode,lpOverlapped invoke MessageBox,0,0,0,0 ;для теста .finish: ret endp struct OVERLAPPED Internal dq 0 InternalHigh dq 0 union struct Offset dd 1024 OffsetHigh dd 0 ends Pointer dq 0 ends hEvent dq 0 ends lpoverlap OVERLAPPED horhe rb 1024 Как я понял из msdn когда закончиться чтение, функ-я ReadFileEx, вызовет процедуру FileIOCompletionRoutine и должен появиться тестовый мессейчбокс.... но он не появляться.. GetLastError на всех стадиях выдает "операция прошла успешно" . Что я делаю не так?
Спасибо за ответ, вызов функции при завершении чтения получилось, Одного понять не могу, когда произошел первый вызов SleepEx то процесс завис в ожидании сигнала не на 100мс, как я указал, а на время необходимое для скачки файла в оперативку,почему SleepEx блокирует процесс не на 100мс? ,ведь процесс должен находиться в алертном состоянии если файл не был докачен только на 100 мс, а потом выходить из него и следовательно и из блокировке? invoke GetProcessHeap invoke HeapAlloc,rax,0,125*1024*1024 mov [pmemory],rax invoke CreateFile,_testfile,GENERIC_READ,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0 mov [hfile],rax invoke ReadFileEx,[hfile],[pmemory],125*1024*1024,lpoverlap,FileIOCompletionRoutine testreadiscomlete: invoke SleepEx,100,1 \\\ побочные функции в цикле \\\ dec [time] jnz testreadiscomlete ... proc FileIOCompletionRoutine ErrorCode,ErrorCode,lpOverlapped invoke MessageBox,0,0,0,0 ;для теста jmp windestroy .finish: ret endp struct OVERLAPPED Internal dq 0 InternalHigh dq 0 union struct Offset dd 1024 OffsetHigh dd 0 ends Pointer dq 0 ends hEvent dq 0 ends lpoverlap OVERLAPPED horhe rb 1024
Уверены что проходит именно 100ms? FILE_FLAG_NO_BUFFERING не установлен, а значит скорее всего файл уже в кэше, а кэш это память и читается явно не 100ms. З.Ы. Ещё добавлю в догонку. Читать асинхронно более 64 мегабайт на 32-бит машине и 32 мегабайт на 64-бит, нельзя. Необходимо читать соответствующими частями. Это ограничение внутреннего буфера винды.
Так там я поочередно подгружал разные файла обьемом 1-2 гб(на машине всего 4 гб), при первой! загрузки такого файла(нет еще буферезации) тратиться около 1-2 минут на файл(носитель медленный), следовательно исходя из вышеописанного кода прочие функции должны выполняться большое кол-во раз в цикле ожидания: testreadiscomlete: invoke SleepEx,100,1 \\\ побочные функции в цикле \\\ dec [time] jnz testreadiscomlete , но они не выполняются не разу! SleepEx блокирует процесс почему то на время необходимое для ПОЛНОГО чтения всего не буферезированного файла..... Почему ?
SleepEx не может выполняться больше time interval. Но дедлоки возможны, почитайте об этом в msdn. Попробуйте ещё WaitForSingleObjectEx. Но скорее всего проблема в чём-то другом.
это из МСДН? возможно будет проще создать ветвь процесса и заставить ее синхронно читать а вторым процессом делать все остальное и контролировать читающею ветвь, правда расходы больше будут....
Не совсем. 64mb-limitation По моему тоже проще. Иначе придётся в калбэке делать повторный вызов чтения файла. Но ведь этот вызов произойдёт только тогда, когда поток находится в alertable wait state и это плохо. Не вижу чтобы расходы при создании своего потока были-бы больше, по моему они одинаковы.
Самое обидное что когда все это только затевал, пришла первая идея что надо второй процесс для копирования делать, и интуиция подсказывала что в винде все равно асинхронное чтение схожим образом реализовано через второй процесс и выигрыш при использовании ReadFileEx будет минимальный, и вот потратил кучу времени и сил пришел к тому что тогда был прав.... Просто супер....