Using the C++11 standard library (with the only help of boost::thread eventually) is there a clean way to implement a N readers - 1 producer solution, where all the readers, once notified at the same time (with std::condition_variable::notify_all() for example) by the producer, are guaranteed to enter their critical section before the producer will eventually enter its critical section a second time. In other words, all the notified readers must observe the same state of the shared resource. Once the producer noties the N readers, it cannot modify the shared resource until all the N readers have finished their reading. Note that boost::barrier is not really what I need, as I do not know N in advance. N may vary from one notification to another.
You could use atomic counters, with some polling from the producer thread.
When the counter reaches either N or 0 (it's up to you) then the producer gets to work and produce whatever it needs to produce. Before notifying the condition variable, the producers sets the counter to 0 (or N).
When a reader is done, it simply increases (or decreases) the counter.
What you describe is called a barrier
Related
I'm trying to implement a multi-in multi-out interthread channel class. I have three mutexes: full locks when buffer is full. empty locks when buffer is empty. th locks when anyone else is modifying buffer. My single IO program looks like
operator<<(...){
full.lock() // locks when trying to push to full buffer
full.unlock() // either it's locked or not, unlock it
th.lock()
...
empty.unlock() // it won't be empty
if(...)full.lock() // it might be full
th.unlock()
operator>>(...){
// symmetric
}
This works totally fine for single IO. But for multiple IO, when consumer thread unlocks full, all provider thread will go down, only one will obtain th and buffer might be full again because of that single thread, while there's no full check anymore. I can add a full.lock() again of course, but this is endless. Is there anyway to lock full and th at same time? I do see a similar question about this, but I don't see order is the problem here.
Yes, use std::lock(full , th);, this could avoid some deadlocks
for example:
thread1:
full.lock();
th.lock();
thread2:
th.lock();
full.lock();
this could cause a deadlock, but the following don't:
thread1:
std::lock(full, th);
thread2:
std::lock(th, full);
No, you can't atomically lock two mutexes.
Additionally, it looks like you are locking a mutex in one thread and then unlocking it in another. That's not allowed.
I suggest switching to condition variables for this problem. Note that it's perfectly fine to have one mutex associated with multiple condition variables.
No, you cannot lock two mutexes at once, but you can use a std::condition_variable for the waiting threads and invoke notify_one when you are done.
See here for further details.
Functonality you try to achieve would require something similar to System V semaphores, where group of operations on semaphors could be applied atomically. In your case you would have 3 semaphores:
semaphore 1 - locking, initialized to 0
semaphore 2 - counter of available data, initialized to 0
semaphore 3 - counter of available buffers, initialized how much buffers you have
then push operation would do this group to lock:
check semaphore 1 is 0
increase semaphore 1 by +1
increase semaphore 2 by +1
decrease semaphore 3 by -1
then
decrease semaphore 1 by -1
to unlock. then to pull data first group would be changed to:
check semaphore 1 is 0
increase semaphore 1 by +1
decrease semaphore 2 by -1
increase semaphore 3 by +1
unlock is the same as before. Using mutexes, which are special case semaphores most probably would not solve your problem this way. First of all they are binary ie only have 2 states but more important API does not provide group operations on them. So you either find semaphore implementation for your platform or use single mutex with condition variable(s) to signal waiting threads that data or buffer is available.
I am trying to develop an application with one producer and several consumers.
The producers is one process and each consumer is one process. The shared resource is some kind of buffer in the shared memory.
The producer should work completely independent from the consumers. It should not be blocked in any case. Therefor the consumers are responsible to check if the data they read from the shared memory is valid and handle it if the producer has already overwritten the data. (They do this using some kind of hashing. Not important.)
The consumers should be informed when new data is available in the buffer. I think boost interprocess conditions are suitable for this usecase. (More suitable would be boost signals2, but this library is not working in an interprocess way).
Conditionas always need a mutex. But I do not need the mutex in my producer. In the consumers I only need the mutex for condition#wait.
Is it ok to only use the codnition#notify_all in the producer and do not use the mutex? Or is this an abuse of the library?
Thanks in advance
It's okay to signal without holding the mutex, but it could lead to worst-case behaviour in rare cases (thread starvation).
Signaling under the mutex guarantees fair scheduling of the waiters under POSIX as far as I am aware ¹
That said, I think the commenters are right when they smell overcomplication in the design. I'd simplify. Optimize when you need it.
¹ See e.g. here: http://linux.die.net/man/3/pthread_cond_signal
The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal().
The producer should work completely independent from the consumers. It
should not be blocked in any case.
Why not? This should not affect the performance if you do not lock too frequently. You can have a data counter in shared memory and you would lock access to that counter only. Data can be stored in circular buffer in shared memory and access to it does not need to be locked because consumers check how much data is available to read using counter. Of course consumers need to read data fast enough. If the data is overwritten then the internal consumer counter can be reset to the value of interprocess counter.
Also producer can store data using many threads. Each thread can calculate future position of the data at the beginning of the thread and then update the counter after the data is stored at the end of the thread. Then additional locking is needed for future position calculations so that this value can be passed between threads.
In details, the non-multithreaded scenario could work like this:
Producer loop:
receive X samples of data
lock access to interprocess counter, increment the counter, unlock the access
Then each consumer has it's own internal counter so that it can compare with interprocess counter if and how much data is available to read (simply polling for data):
Consumer loop:
lock access to interprocess counter, read the counter value, unlock the access
compare the read value with internal counter
if values equal // no data available
sleep, then continue to the beginning of the loop
else if data overwritten // no need for hashing here, counter can be use to figure that out although doing it this way is probably a bit risky
set internal counter to the value of the interprocess counter
then continue to the beginning of the loop
else
read available data
increment internal counter
I have a question regarding threads. It is known that basically when we call for mutex(lock) that means that thread keeps on executing the part of code uninterrupted by other threads until it meets mutex(unlock). (At least that's what they say in the book) So my question is if it is actually possible to have several scoped WriteLocks which do not interfere with each other. For example something like this:
If I have a buffer with N elements without any new elements coming, however with high frequency updates (like change value of Kth element) is it possible to set a different lock on each element so that the only time threads would stall and wait is if actually 2 or more threads are trying to update the same element?
To answer your question about N mutexes: yes, that is indeed possible. What resources are protected by a mutex depends entirely on you as the user of that mutex.
This leads to the first (statement) part of your question. A mutex by itself does not guarantee that a thread will work uninterrupted. All it guarantees is MUTual EXclusion - if thread B attempts to lock a mutex which thread A has locked, thread B will block (execute no code) until thread A unlocks the mutex.
This means mutexes can be used to guarantee that a thread executes a block of code uninterrupted; but this works only if all threads follow the same mutex-locking protocol around that block of code. Which means it is your responsibility to assign semantics (or meaning) to each individual mutex, and correctly adhere to those semantics in your code.
If you decide for the semantics to be "I have an array a of N data elements and an array m of N mutexes, and accessing a[i] can only be done when m[i] is locked," then that's how it will work.
The need to consistently stick to the same protocol is why you should generally encapsulate the mutex and the code/data protected by it in a class in some way or another, so that outside code doesn't need to know the details of the protocol. It just knows "call this member function, and the synchronisation will happen automagically." This "automagic" will be the class correcrtly implementing the protocol.
A crucial consideration when deciding between a mutex per array and a mutex per element is whether there are operations - like tracking the number of "in-use" array elements, the "active" element, or moving a pointer-to-array to a larger buffer - that can only be done safely by one thread while all the others are blocked.
A lesser but sometimes important consideration is the amount of extra memory more mutexes use.
If you genuinely need to do this kind of update as quickly as possible in a highly contested multi-threaded program, you may also want to learn about lock-free atomic types and their compare-and-swap / exchange operations, but I'd recommend against considering that unless profiling the existing locking is significant in your overall program performance.
A mutex does not stop other threads from running completely, it only stops other threads from locking the same mutex. I.e. while one thread is keeping the mutex locked, the operating system continues to do context switches letting other threads run also, but if any other thread is trying to lock the same mutex its execution will be halted until the mutex is unlocked.
So yes, you can indeed have several different mutexes and lock/unlock them independently. Just beware of deadlocks, i.e. if one thread can lock more than one mutex at a time you can run into a situation where thread 1 has locked mutex A and is trying to lock mutex B but blocks because thread 2 already has mutex B locked and it is trying to lock mutex A..
Its not completely clear that your use case is:
the threads gets a buffer assigned on that they have to work
the threads have some results and request a special buffer to update.
On the first variant you need some assignment logic that assigns a buffer to a thread.
This logic has to be exectued in an atomic way. so the best is to use a mutex to protect the assignment logic.
On the other variant it may be the best to have a vector of mutexes, one for each buffer element.
In Both cases the buffer does not need a protection because it (or better each field of it) is only accessed from one thread at a time.
You also may inform yourself about 'semaphores'. These contain a counter that allows to manage ressources that have a limited amount but more than one. Mutexes are a special case of semaphores with n=1.
You can have mutex per entry, C++11 mutex can be easily converted into an adaptive-spinlock, so you can achieve good CPU/Latency tradeoff.
Or, if you need very low latency yet have enough CPUs you can use an atomic "busy" flag per entry and spin in a tight compare-exchange loop on contention.
From experience, though, the best performance and scalability are achieved when concurrent writes are serialized via a command queue (or a queue of smaller immutable buffers to be concatenated at destination) and a single thread processing the queue.
I have four threads which has its own private queue and a private'int count' member, whenever a task is produced from the program thread, it should be enqueued to a thread's queue which has minimum 'int count' among the threads.
whenever a task is pushed into the queue, the private 'int count' should be increased by 1
whenever a task is popped out of the queue, the private 'int count' should be decreased by 1
so, the 'int count' is dynamically changing regarding to tasks push,pop operation and the program thread will dispatch the task to the queue with the lowest, (or first zero found), count.
This is the underlying logic of the program.
I am working in c++ programing language in linux multithreading library implementing a multi-rate synchronous data flow paradigm.
could you please give some coding ideas for implemenating this logic. ie.
1.Initializing all private int queue counter =0
2.counter++ when task are pushed,
3.counter-- when tasks are popped,
4.Task disptacher sees the private int count of each thread.
5.Dispatches tasks to queue which has minimum count
I have four threads which has its own private queue and a private'int
*count' member, whenever a task is produced from the program thread, i*t
should be enqueued to a thread's queue which has minimum 'int count'
*among the threads.*
whenever a task is pushed into the queue, the private 'int count'
*should be increased by 1 whenever a task is popped out of the queue,*
the private 'int count' should be decreased by 1
Ok, so Basically your program thread is the producer and you have 4 consumer threads. By using a queue in each thread you will be minimizing the time spent by the main thread interacting with the consumers. N.B. You need to consider whether your threads are going to be starved / or overflow - I.E. if the single producer will create "work" at a rate that warrants 4 consumers, or if 4 consumers will be swamped.
naive approach
So you need to synchronize the queue access / increment meaning that you need a mutex to stop the consumer accessing anything while the count and queue are modified. The easiest way is to do the synchronization would be to have a method (E.G. enqueue(Item& item) ) which locks the mutex within it.
C++11 : Mutex http://en.cppreference.com/w/cpp/thread/mutex
Additionally if starvation is an issue (or overflow) you will need to use some signalling to stop the relevant threads activity (Starved - stop consumers to avoid CPU usage, Overflow - stop producer while consumers catch up). Usually these signals are implemented using condition variables.
C++11 : Condition variables : http://en.cppreference.com/w/cpp/thread/condition_variable
so, the 'int count' is dynamically changing regarding to tasks
*push,pop operation and the program thread will dispatch the task t*o
the queue with the lowest, (or first zero found), count.
So the situation is slightly complicated here, in that the threads that you want to populate will be the ones with the least work to do. This requires that you inspect the 4 counts and choose the queue. However because there is only one producer you can probably just scan for the queue without locking. The logic here is that the consumers will not be affected by the read, and the choice of thread would not really be incorrect even with the consumers working during that choice.
So I would have an array of thread objects, each of which would have the count, and a mutex for locking.
1.Initializing all private int queue counter =0
Initialize the counts in the constructors - make sure that the producer isn't working during initialization and synchronization won't be an issue.
2.counter++ when task are pushed,
*3.counter-- when tasks are popped,*
Implement 2 methods on the thread object to do the enqueing / dequeuing and in each use a lock_guard to lock the mutex (RAII technique). Then push/pop item to/from the queue and increment/decrement as applicable.
C++11: lock_guard http://en.cppreference.com/w/cpp/thread/lock_guard
4.Task disptacher sees the private int count of each thread.
*5.Dispatches tasks to queue which has minimum count*
As I said above if there is only one you can simply scan through the array of objects and choose (maintain an index to) the thread object where the counter (add a getCount() method)is the lowest. It will most likely be the lowest even with the consumers continuing their work.
If there are multiple threads producing work then you might need to think about how you want to handle the 2 threads enquing to the same thread (It might not matter)
I came across a problem in multithreading, Model of multithreading is 1 Producer - N Consumer.
Producer produces the data (character data around 200bytes each), put it in fixed size cache ( i.e 2Mil). The data is not relevent to all the threads. It apply the filter ( configured ) and determines no of threads qualify for the produced data.
Producer pushes the pointer to data into the queue of qualifying threads ( only pointer to the data to avoid data copy). Threads will deque and send it over TCP/IP to their clients.
Problem: Because of only pointer to data is given to multiple threads, When cache becomes full, Produces wants to delete the first item(old one). possibility of any thread still referring to the data.
Feasible Way : Use Atomic granularity, When producer determines the number of qualifying threads, It can update the counter and list of thread ids.
class InUseCounter
{
int m_count;
set<thread_t> m_in_use_threads;
Mutex m_mutex;
Condition m_cond;
public:
// This constructor used by Producer
InUseCounter(int count, set<thread_t> tlist)
{
m_count = count;
m_in_use_threads = tlist;
}
// This function is called by each threads
// When they are done with the data,
// Informing that I no longer use the reference to the data.
void decrement(thread_t tid)
{
Gaurd<Mutex> lock(m_mutex);
--m_count;
m_in_use_threads.erease(tid);
}
int get_count() const { return m_count; }
};
master chache
map<seqnum, Data>
|
v
pair<CharData, InUseCounter>
When producer removes the element it checks the counter, is more than 0, it sends action to release the reference to threads in m_in_use_threads set.
Question
If there are 2Mil records in master cache, there will be equal
number of InUseCounter, so the Mutex varibles, Is this advisable to have 2Mil mutex varible in one single process.
Having big single data structure to maintain the InUseCounter will
cause more locking time to find and decrement
What would be the best alternative to my approach to find out the references, and who
all have the references with very less locking time.
Advance thanks for you advices.
2 million mutexes is a bit much. Even if they are lightweight locks,
they still take up some overhead.
Putting the InUseCounter in a single structure would end up involving contention between threads when they release a record; if the threads do not execute in lockstep, this might be negligible. If they are frequently releasing records and the contention rate goes up, this is obviously a performance sink.
You can improve performance by having one thread responsible for maintaining the record reference counts (the producer thread) and having the other threads send back record release events over a separate queue, in effect, turning the producer into a record release event consumer. When you need to flush an entry, process all the release queues first, then run your release logic. You will have some latency to deal with, as you are now queueing up release events instead of attempting to process them immediately, but the performance should be much better.
Incidentally, this is similar to how the Disruptor framework works. It's a high performance Java(!) concurrency framework for high frequency trading. Yes, I did say high performance Java and concurrency in the same sentence. There is a lot of valuable insight into high performance concurrency design and implementation.
Since you already have a Producer->Consumer queue, one very simple system consists in having a "feedback" queue (Consumer->Producer).
After having consumed an item, the consumer feeds the pointer back to the Producer so that the Producer can remove the item and updates the "free-list" of the cache.
This way, only the Producer ever touches the cache innards, and no synchronization is necessary there: only the queues need be synchronized.
Yes, 2000000 mutexes are an overkill.
1 big structure will be locked longer, but will require much less lock/unlocks.
the best approach would be to use shared_ptr smart pointers: they seem to be tailor made for this. You don't check the counter yourself, you just clean up your pointer. shared_ptr is thread-safe, not the data it points to, but for 1 producer (writer) / N consumer (readers), this should not be an issue.