Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the best way to synchronize container access between multiple threads in real-time application

I have std::list<Info> infoList in my application that is shared between two threads. These 2 threads are accessing this list as follows:

Thread 1: uses push_back(), pop_front() or clear() on the list (Depending on the situation) Thread 2: uses an iterator to iterate through the items in the list and do some actions.

Thread 2 is iterating the list like the following:

for(std::list<Info>::iterator i = infoList.begin(); i != infoList.end(); ++i)
{
  DoAction(i);
}

The code is compiled using GCC 4.4.2.

Sometimes ++i causes a segfault and crashes the application. The error is caused in std_list.h line 143 at the following line:

_M_node = _M_node->_M_next;

I guess this is a racing condition. The list might have changed or even cleared by thread 1 while thread 2 was iterating it.

I used Mutex to synchronize access to this list and all went ok during my initial test. But the system just freezes under stress test making this solution totally unacceptable. This application is a real-time application and i need to find a solution so both threads can run as fast as possible without hurting the total applications throughput.

My question is this: Thread 1 and Thread 2 need to execute as fast as possible since this is a real-time application. what can i do to prevent this problem and still maintain the application performance? Are there any lock-free algorithms available for such a problem?

Its ok if i miss some newly added Info objects in thread 2's iteration but what can i do to prevent the iterator from becoming a dangling pointer?

Thanks

like image 789
red.clover Avatar asked Jan 16 '10 11:01

red.clover


People also ask

Which method is used when you allow only one thread at a time to access application state variables?

The lock statement is one of the simplest and most common tools for C# developers writing multithreaded applications. It can be used to synchronize access to blocks of code, achieving thread safety by allowing only one thread at a time to execute the code in that block.

What is used for inter thread synchronization when you have multiple threads spawned off?

The Synchronized block can be used to perform synchronization on any specific resource of the method. Only one thread at a time can execute on a particular resource, and all other threads which attempt to enter the synchronized block are blocked. Synchronized block is used to lock an object for any shared resource.

What do you mean by synchronization between threads?

Thread synchronization is the concurrent execution of two or more threads that share critical resources. Threads should be synchronized to avoid critical resource use conflicts. Otherwise, conflicts may arise when parallel-running threads attempt to modify a common variable at the same time.


1 Answers

Your for() loop can potentially keep a lock for a relatively long time, depending on how many elements it iterates. You can get in real trouble if it "polls" the queue, constantly checking if a new element became available. That makes the thread own the mutex for an unreasonably long time, giving few opportunities to the producer thread to break in and add an element. And burning lots of unnecessary CPU cycles in the process.

You need a "bounded blocking queue". Don't write it yourself, the lock design is not trivial. Hard to find good examples, most of it is .NET code. This article looks promising.

like image 145
Hans Passant Avatar answered Oct 06 '22 16:10

Hans Passant