News:

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

Threads

Started by oex, October 18, 2010, 06:52:07 PM

Previous topic - Next topic

oex

Hey Guys,

It's a while since I used threads last properly (back in my C++ days).... I just want to make sure I remember correctly.... 2 threads can *read* from the same memory location but not *write* to the same memory location without conflict right? Or is it more involved than that? Can I have one thread reading a memory address while another writes to it or is that a crash conflict? I've been using other methods for multi-threading up until now however I want to clean up my app and make it properly thread-safe.... I could probably test it out or find the stuff on an old HD but it's probably a lot quicker getting a reminder here :lol
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

clive

Threads within the same process get to see exactly the same memory, and can read and write to it without issue. Where you get problems is with synchronization between thread(s), and race conditions, and who commits to memory first/last. This is compounded in multi-processor (or hyperthreadded) systems because two things can actually happen at once in parallel, where-as in a single processor a task might switch but things occur more serially. If you are accessing a memory structure where you need to write the whole thing atomically, you should use a semaphore/mutex to take ownership of the memory, and you might need to do this also when reading it if you can't deal with the content changing on you.

Also watch out for global variables, each thread does not typically have it's own copy, so having a subroutine stash something in one is not thread-safe. If you can, use the stack, each thread has it's own. Microsoft has a (Thread Local Storage) TLS scheme using the FS segment register, but that might be more complicated than you want.

http://msdn.microsoft.com/en-us/library/ms686749%28VS.85%29.aspx
It could be a random act of randomness. Those happen a lot as well.

oex

Thanks Clive, yep it's the global memory space that is my main concern, I never had any problem with local thread memory in the past.... I will check out that link you posted I want interaction between threads and interactive management of threads from the main process thread so I dont want to clash with memory read/writes to the same global memory space....

hmm on reading your response and checking that stuff on TLS I'm still not entirely clear....

oexGlobalVariable dd 0

If I write data to oexGlobalVariable in a secondary thread and my application tries to read it in the primary thread at the same time my application will crash right?

If not I should be able to create a global hash array and have all threads that need assistance note this requirement and service them one by one.... Indeed I seem to remember I can do this with Suspend and Resume Thread functions?

Maybe my method is just very inefficient and there is a better way? Like the one you mentioned? The threads atm dont have massive priority ie they can resume within 10ths of a second without problem atm however if I'm going about this completely the wrong way?....

According to Bogdan:
"Also keep in mind that TLS is only for lazy HLL programmers that do not have access to a function to allocate memory and allocate a memory buffer per thread. TLS does this "automatically" at PE start time but this can be done "by hand" by the programmer very easy and with more power. Hence there is little purpose for using TLS."

http://www.masm32.com/board/index.php?topic=9881.msg72800#msg72800

I think maybe you were just trying to make it easy for me Clive :bg
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

clive

Well I wouldn't say it will crash, because the processor(s) pretty much take care of arbitrating access and synchronizing caches/memory, and writes will generally percolate out of the write buffers in program order. Undesired or unexpected behaviour might occur, and that might cause a lock up or crash.

What will hurt you is if two threads write different values to the same location, say a zero and a one, and the zero gets there last, and then those or other threads deadlock waiting for it to contain one.

Now if I had multiple threads which were identical doing similar things, I'd allocate each it's own context (memory structure), and use that to store internal state information, and not global variables. All the functions in the thread would reference that context, store handles and variables in it, and not access other memory unless tasked to do so. That would scale well, because you could spawn additional copies of the same threaded code, depending on available cores or work that was required, and each would run autonomously and not interfere with each other. They would share a common view of memory, but know nothing about each other, or the context of another.

To communicate between them you could use pipes, events, semaphores, mutexs, etc.

Say you had a generic thread which could do PCM-to-MP3 conversion, and a long list of WAV files to convert. Each thread would lock the file list, pick and remove the top file, and then unlock the list. It would then convert the file completely. Once done it would repeat the process. If you had 6 cores, each could have it's own thread, and none would need to know about the others.

It could be a random act of randomness. Those happen a lot as well.