   Sending data from one thread to another
  Hi,I want to send Data from one thread to another. So Thread1 finished working on some Objects and sends it to Thread2. Thread1 will never need to read/write the data again. I am relatively new with threads.Using Visual Studio C++ Express 2010 and Windows-Api. I could switch to a library, so suggestions wouldn't hurt, but i would like to stick with it right now.It would be used for example by a loader thread. It has finished loading some data from the hard disk and wants to pass it now to the resource manager (in another thread). After passing it the loader can continue loading other data. The resource thread should only have to look if something is there and if not continue as normal. Or another example would be computing animations.Solutions I found:Solution 1 - Using a mutex. This will work but it doesn't seem right, because one threads only reads and the other only writes.Solution 2 - Critical section. Probably better than a mutex in this case (?) but there should be something better, lock free maybe?Solution 3 - This would be lock free but I'm not sure if this works right. Using one or better two volatile booleans. One called "dataIsAvailable" and the other "readerHasFinishedReading" or something like this.Which of the solutions would be best, and is there (hopefully) an even better solution?Thanks,lm   
It's the Producer/Consumer problem?You'd have the main thread "produce" items to load. The loader "consumes" them. You then place the loaded resources in a list (using a critical section to lock the list), and your main thread would check the list (using a critical section) for loaded items.I'd also sugest using a wrapper like boost::thread. Yes you can do the lockfree thing too. I've never played with that. But I've also read that it is only faster under some conditions.   ;  Message Passing would be the most decoupled solution.And trying to impliment 'lock free' using two bools is going to end in a world of pain as setting a bool isn't an atomic operation; the various Interlock* functions are needed at this point.As you are using Visual Studio 2010, and if you don't mind being tied to Windows, then MS's Concurrency Runtime is worth a look; if nothing else if has buffers in place already to construct a message passing system.   ;Quote:Original post by phantomAnd trying to impliment 'lock free' using two bools is going to end in a world of pain as setting a bool isn't an atomic operation;Sorry to jump in, but having not used threads in C++ before, I'm confused as to why bool would not be atomic...seems to fly against common sense. I know it's atomic in C#.Is this just another area of C++ weirdness?   ;Quote:Original post by djzSorry to jump in, but having not used threads in C++ before, I'm confused as to why bool would not be atomic...C++ doesn't have a concept of threading or consistent memory model. This leads to all kinds of funny scenarios.On a multi-core different cores might have cached copies.Due to padding, bool might be written as 4 bytes, and they might not be aligned, so depending on CPU the write itself might not be atomic.C++ optimizer is free to reorganize code, so as far as synchronization goes, volatile qualifier is the minimum that must be used, but that isn't necessarily implemented in a consistent manner.And probably tons of other weird cases.Quote:seems to fly against common sense.Not really. Concept of atomic writes depends on certain CPU behavior, memory architecture and synchronization - it's an almost purely hardware-specific issue, one which may differ even between different versions of same series of hardware. C++ is vast abstraction over that, so it's up to compiler whether it generates appropriate code. And C++ standard simply doesn't touch any of that.Quote:I know it's atomic in C#.Because implementation of VM guarantees is via implementation of memory model.But volatile is still needed, even in C#.   ;  If you're going to use those two bools, then on Windows: * You have to use the type "volatile LONG" * To write to the variable, you have to use InterlockedExchange instead of = * To read the variable, write "MemoryBarrier();" immediately after you read the value."Atomic" has a few definitions. Technically, on a regular x86 processor, then as long as your 32bit variable is correctly aligned, then reads/writes *are* atomic, in that all 4 bytes of the variable will be read/written at once - it's not possible for half the read/write to occur and the other half to be affected by a race condition.However, some CPUs may choose to re-order instructions, or re-order reads/writes to memory, so code like this:memcpy( sharedData, myData, ... );dataIsAvailable = true;...can actually be executed in this order:dataIsAvailable = true;memcpy( sharedData, myData, ... );...which means the other thread might see the flag as being true before the data is actually available.The Interlocked API solves this issue by inserting "Memory Fence" instructions, which enforce the correct ordering of these memory operations.This is all pretty hairy stuff though, so you may be better off just sticking to critical sections until your profiler shows that they're a bottleneck.[Edited by - Hodgman on April 26, 2010 8:46:13 PM];  Thanks for all the answers. Critical sections are the easiest to implement so I will stick with them for now. Although I will look into how passing messages to another thread works.Multithreading in C++, especially learning MT, is a bit of a pain, 'cause there is no C++ MT standard. Hopefully C++0x will change that.   ;Quote:Original post by lm-chanThanks for all the answers. Critical sections are the easiest to implement so I will stick with them for now. Although I will look into how passing messages to another thread works.Multithreading in C++, especially learning MT, is a bit of a pain, 'cause there is no C++ MT standard. Hopefully C++0x will change that.Which is why you're probably best off using boost.thread, as suggested by KulSeran. If multithreading ever makes it into the C++ standard, there's a pretty good chance it'll be based on boost.thread.;Quote:Original post by lm-chanThanks for all the answers. Critical sections are the easiest to implement so I will stick with them for now. Although I will look into how passing messages to another thread works.Yeah Critical sections are your basic easy method of doing it. Make sure you use RAII with them. E.g. CComAutoCriticalSection etc.Posting messages between threads is definitely another good way to do it. For that just keep track of the thread IDs and then it's just PostThreadMessage.Both of the above are used frequently in a large project I work on daily.IMHO lock-free stuff is sometimes overhyped, and doesn't always solve the problem at the right level of granularity. I would suggest only going there as a last resort, i.e. when profiling tells you there is a problem and it's not one easily solved by altering your locking strategy.   