Subj : Re: Challenge: Multithreading & Synchronization To : comp.programming.threads From : Maciej Sobczak Date : Fri May 20 2005 12:46 pm Hi, Uenal Mutlu wrote: > We've usually the following cases: [...] Really? What about the multithreaded program, where all threads use stdout to log their actions? puts("I'm doing this."); puts("I'm doing that."); Your idea of using the Lockable template breaks here, because there is nothing around that you could wrap with it. Which "case" would you apply here? But anyway - all the cases you show are very specific to the operation with a single value object (some vector). This is not what happens in general. > // case1: exclusive access to an object: > void f() > { > Locker L(vec.m); > for (size_t i = 0; i < vec.size(); i++) > { > // manipulate vec > } > } Let's say that I want to print the content of the vector to stdout. The above will not help me - I do not want other functions printing anything else in the middle (this might even crash the program). > // case2: shared access to an object: > void f() > { > for (size_t i = 0; i < vec.size(); i++) > { > Locker L(vec.m); > // manipulate vec > } > } This is broken for the reasons already explained by Doug. And if you assume that the vector is never modified while the loop is executing, then you do not need any mutex at all. Just ensure that you see all the previous modifications you want to see, before you start the loop. > With many threads and high concurrency case2 mostly would > lead to the fastest performance, although it might look counter-intuitive. It won't (lead to the fastest performance) because it is (counter-intuitive). > This case would be a good choice for a realtime application. > But mostly case1 is sufficient. > Case0 usually would lead to the slowest performance. It does not matter how fast your program is, if it is incorrect. You should stop thinking in terms of separate objects, which you think need synchronization. You should synchronize *activities* instead. Of course, in *some* cases, the activities will be associated with a single object and it is then when it might make sense to tightly associate a mutex with a single value object. A queue used between threads is a good example, but apart from such specific examples, you should synchronize *activities* and you shoule keep *invariants* of your program. -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/ .