News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

asynchronous file I/O

Started by sinsi, February 12, 2010, 10:19:41 AM

Previous topic - Next topic

sinsi

Has anyone used this? I was wondering whether to use this or a new thread for reading a file.
For example, a text or hex viewer, all you need is the first bit of a file, the rest can be processed in the background.
Both methods would be able to interact with the user, but is one better than the other?
Light travels faster than sound, that's why some people seem bright until you hear them.

Farabi

Quote from: sinsi on February 12, 2010, 10:19:41 AM
Has anyone used this? I was wondering whether to use this or a new thread for reading a file.
For example, a text or hex viewer, all you need is the first bit of a file, the rest can be processed in the background.
Both methods would be able to interact with the user, but is one better than the other?

I dont think multithreading will make the hardisk read speed faster, it does not affecting it. Except off course, the harddisk reader iron is more than one.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

sinsi

I'm not worried about the speed of reading, just the ability to e.g. click on 'cancel' instead of the ReadFile blocking.
Light travels faster than sound, that's why some people seem bright until you hear them.

redskull

Asynchronous I/O generally gives better performance and scales better, but multi-threading is much simplier to use.  In the case of a simple text file, I would go with a seperate thread; if you are not "doing" anything else, and just want control over the GUI for the users sake, there's no reason to get involved with alertable wait states and all that.

-r

Strange women, lying in ponds, distributing swords, is no basis for a system of government

sinsi

Quote from: redskullbut multi-threading is much simplier to use
Funny, I thought that was harder...not having any experience with threads that's not suprising eh?

I figure that windows will do its own optimising with an async call, does that negate having a thread do it?
Like I say, speed is not an issue - I just hate it when a program ignores my clicks. "Cancel you f*cker!!!!!!"
Light travels faster than sound, that's why some people seem bright until you hear them.

dedndave

threads are easy   :P
even I can get a thread going
after that, i am lost - lol

just make the file-read thread keep track of the file pointer so your main program knows how much of the file has been read
that means you need a little handshaking so they don't try to access the pointer at the same time

sinsi

Quote from: daveeven I can get a thread going
Alright, I am on my way!
Light travels faster than sound, that's why some people seem bright until you hear them.

redskull

Quote from: sinsi on February 12, 2010, 01:19:58 PM
Funny, I thought that was harder...not having any experience with threads that's not suprising eh?

To each his own; i guess whichever one you have more experience with would be the one to choose.  The main benefit of AIO is for when you have lots of IO calls to do (like, in the hundreds); if you have a single thread with blocking calls, you can't do the next one until the first one is done.  If you have a seperate thread for each one, you load down the system with more threads than it can handle.  With overlapped I/O, you get the best of both worlds.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

dedndave

it is easy
write a proc like you would any other
replace the RET with ExitThread
instead of invoke'ing the proc, use CreateThread
if you want to use the same thread code for multiple threads, you can use GetThreadID
and use that value to index into a data array so each thread has it's own data

jj2007

Thanks, Dave - that was really a cute cookbook :U

Here is my translation:

include \masm32\include\masm32rt.inc
MyThread PROTO: DWORD

.data?
hThread dd ?
TheFlag dd ?
ThreadID dd ?
ExitCode dd ?

.code
start: ; invoke Sleep, 0  ; sometimes this was needed, no idea why
invoke CreateThread, 0, 0, offset MyThread, 123, 0, offset ThreadID
mov hThread, eax
print str$(eax), 9, " is the thread handle", 13, 10
.Repeat
invoke Sleep, 50
print "*"
.Until rv(GetExitCodeThread, hThread, offset ExitCode)==0 || ExitCode!=STILL_ACTIVE
print chr$(13, 10)
print str$(TheFlag), 9, " is the value that MyThread moved into TheFlag", 13, 10
print str$(ExitCode), 9, " is the ExitCode returned by MyThread", 13, 10
print str$(ThreadID), 9, " is the ThreadID", 13, 10
getkey
exit

MyThread proc singleArg:DWORD
  invoke Sleep, 600
  mov TheFlag, 321
  invoke ExitThread, singleArg
MyThread endp

end start

dedndave

i was thinking something like this...

.data

ThreadIndexTable dw 8 dup(0)

.data?

ThreadDataArray  dw 64 dup(?)   ;8 threads - 8 dwords each thread

.code

start:

;create 8 threads using the same routine

invoke ExitProcess

ThreadCode PROC

invoke GetThreadID

;find an empty entry in ThreadIndexTable to place the thread ID

;from the position in ThreadIndexTable, calculate the index into ThreadDataArray

;now each thread has 8 dwords of data, unique from the other threads using the same code

;
;
;

invoke ExitThread

ThreadCode ENDP

        END     start

depending on how the OS hands out thread ID's, you may not need the ThreadIndexTable

qWord

ExitThread is not really needed - eax+ret does the same.
FPU in a trice: SmplMath
It's that simple!

jj2007

Quote from: qWord on February 12, 2010, 06:34:22 PM
ExitThread is not really needed - eax+ret does the same.

MSDN is a bit cloudy about what really happens:
QuoteExitThread is the preferred method of exiting a thread in C code. However, in C++ code, the thread is exited before any destructors can be called or any other automatic cleanup can be performed. Therefore, in C++ code, you should return from your thread function.

When this function is called (either explicitly or by returning from a thread procedure), the current thread's stack is deallocated, all pending I/O initiated by the thread is canceled, and the thread terminates. The entry-point function of all attached dynamic-link libraries (DLLs) is invoked with a value indicating that the thread is detaching from the DLL.

qWord

QuoteWhen this function is called (either explicitly or by returning from a thread procedure)...
IMO its clear: there is no differenc between ExitThread and RET. Using OllyDbg you can see that both methods end up in a call to
RtlExitUserThread (ntdll).
FPU in a trice: SmplMath
It's that simple!

BlackVortex

I think we should follow the preferred advice for C and not C++  :green