IDDQD
IDDQD

Reputation: 3731

Concurrency efficiency in C++

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

Answers (3)

Thomas
Thomas

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

SergeyA
SergeyA

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

2785528
2785528

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

Related Questions