Reputation: 4115
If there is some code that 2 threads trying to write to the same object at the same time, my understanding is that it will not generate any compile-time error, which is the part of the reason why debugging multithreading program is so difficult. But will this generate a run-time error / exception?
Can anyone suggest any good multithreading debug techniques?
Thanks.
Upvotes: 0
Views: 989
Reputation: 3312
It seems nobody answered how to debug multi threaded code in real time, which is REALLY difficult. Just extremely short delays make the program behave differently and the error may occur only when certain race conditions happen. This can only be investigated with extremely fast tracing, for which Visual Studio is way too slow. Even worse, the trace method becomes really slow when 2 threads call it simultaneously.
It is quite easy to write your own, non blocking (!) trace into memory. Just write the information into a ring buffer. My C++ is not good enough, but in C# the code would look something like this:
const int maxMessages = 0x100;
const int indexMask = maxMessages-1;
string[] messages = new string[maxMessages];
int messagesIndex = -1;
public void Trace(string message) {
int thisIndex = Interlocked.Increment(ref messagesIndex) & indexMask;
messages[thisIndex] = message;
}
A more detailed description for this approach which also collects thread and timing information and outputs the trace nicely is at: CodeProject: Debugging multithreaded code in real time 1
Upvotes: 0
Reputation: 73470
If you're on linux or OS X, then you can use one of the valgrind tools ( hellgrind or drd ) to detect some memory accesses by threads without corresponding mutexes.
However this is not foolproof, and I'd not rely on it catching all your problems .. be very careful with any shared resource.
Upvotes: 1
Reputation: 182753
It may or may not. Concurrent modification is UB on most threading standards, so they make no guarantee about what will happen. Typically, with simple types, one or the other write will "win". (Some platforms guarantee this for aligned, simple types.) With complex types, you may get tearing and wind up with an "in-between" value.
Concurrent writes aren't usually the type of problem you have though. The more common case is overlapping read-modify-write operations. For example, think about two threads trying to add an item to the same queue or linked list. When you add an item to a linked list, there may be a time when the linked list is "broken" and if another thread accesses the linked list while it's broken (in the middle of the modification when it's part way done), things can blow up.
Adding an item to the head of a linked list usually involves something like:
object->next = head->next;
head = object;
If another thread tries to add an object to the linked list after the first line completes but before the second line starts, the results will not be pretty.
Upvotes: 0
Reputation: 11
Two different threads writing to a single object or resource at the same time will corrupt it and this problem is a race condition. In multi threaded programs race conditions are neither a compile-time error or a run-time error/exception. Race condition is a software flaw in managing to share resources, aka interprocess communication, and are nasty because they wreck the data behind the scenes. Running the same program multiple times will result in the output is the result that was expected and in other times not being what was expected.
Preventing race conditions in threads by using mutual exclusion. If only one object or resource is available use mutex, an example is LCD display or a single object, otherwise if there is multiple use a semaphore, an example is four USB ports. Resources are data, and devices. Data is variables, objects, data structures and etc. Devices are LCD display, printers, USB ports, and etc.
Looking at the program as a sequential single thread and decide the separating tasks that need to be done can save the trouble of more time debugging. A word processor is a multi threaded program that is made of a few threads. The imaginary example of the threads are: to read a text file, to display text, to save a text file, and maybe auto-save that runs every five minutes. Threads should be actions that can be preformed and notice all threads in the word processor have text as a resource.
If you already have code or checking values use printf statement instead of cout before and after the object in each thread. See the reason for printf instead of cout here.
All operating systems have interprocess communication, but the API is different. Linux uses POSTIX API and Windows uses Win32 or Windows API, but are used the same way.
Reading Material http://drdobbs.com/cpp/199200938?pgno=1
^-Summarized some of the article into what was written
Upvotes: 1
Reputation: 3256
Accessing the same object from inside two or more different threads would not generate an error either in run time or in a debugger BUT it most probably would screw around with the object in ways that you did not intend to.
The way to handle it in a multi-threaded environment safely is to use mutexes and semaphores. For mutexes check the wikipedia link.
Mutexes are generally used when you want to limit the access to an object by only one thread at a time.
Semaphores on the other hand are a more generic case (mutexes are actually a special case of a semaphore) which have a counter that each thread will increase/decrease depending on the activation/deactivation of the semaphore. When the semaphore reaches 0 it will lock itself and the thread that caused it. For more information on semaphores check the wikipedia page
If you want more specific advice, then I suggest you give us information on the Operating system you are targeting and/or the API you are using since anything having to do with threads (mutexes,semaphores e.t.c.) are OS-specific
Upvotes: 1