Reputation: 3731
I have a function pushMessage()
.
void pushMessage(const char* msg, const int len)
{
for (int i=0;i<len;++i)
queue.push(*(msg+i))
}
The queue in question is a tbb::concurrent_bounded_queue<char>
and has a really large size (assume infinite).
This function is called by two threads. One thread calls the function constantly, another once in a while.
What's the most efficient way to ensure that the contents of the queue do not have a mix of concurrent msg
? My first call was to use mutex, however I'd like to hear more because I am rather new to the world of concurrency, and I'd rather not just jump to the first thing I learn. Much appreciated.
P.S. - I have access to Boost and TBB libraries.
EDIT: The queue is of type char because it is used to send messages byte-by-byte, for speed. The previous implementation was sending the entire messages at a time.
Upvotes: 0
Views: 260
Reputation: 5138
One possible solution might be to uses a boost::lockfree::queue<std::string>
You can then push and pop whole messages without further synchronization.
If, as you say, you must use bytes, you might try boost::lockfree::spsc_queue<char>
. There you have members
size_t write_available(size_t max_size) const
size_type push(T const * t, size_type size)
so together with a mutex you can write something like this in the pushMessage
method
{
boost::lock_guard<boost::mutex> guard( mutex_);
if( queue_.write_available( len ) )
queue_.push( msg, len );
}
Upvotes: 0
Reputation: 62563
You do not have any other choice but a mutex (or semaphore, or critical section - effectively all the same thing). Nothing else will ensure non-interleaved message in current design.
I do, however, question the wisdom of the current design. Why are you having a queue of characters, when the semantic is the whole message? Wouldn't it be better to have a whole message as a single queue element?
Upvotes: 3
Reputation: 5566
What's the most efficient way to ensure that the contents of the queue do not have a mix of concurrent msg?
It has been my experience (but mostly pre-c++11) that any mutex semaphore is 'light duty' when the threads 'seldom' collide. What I infer from this is that context switch must be the high cost action. If the critical section is 'unlocked', the cost of the mutex check is small.
Generally, I use (and recommend) mutex, then follow up with tests to see if the behaviour is adequate.
One maybe useful comparison
a) how many times can one thread enter a mutex guarded critical section (i.e. without competition)
vs
b) how many thread context switches can be completed when enforced using the same mutex.
Upvotes: 0