2016-02-22 48 views
0

我有一个函数pushMessage()C++中的并发效率

void pushMessage(const char* msg, const int len) 
{ 
    for (int i=0;i<len;++i) 
     queue.push(*(msg+i)) 
} 

有问题的队列是一个tbb::concurrent_bounded_queue<char>,有一个真正的大尺寸(假设为无穷大)。

这个函数被两个线程调用。一个线程不断调用函数,另一个线程偶尔调用函数。

什么是确保队列内容没有混合并发msg的最有效方法?我的第一个电话是使用互斥锁,但是我想听到更多,因为我对并发的世界相当陌生,我宁愿不跳到我学习的第一件事情上。非常感激。

P.S. - 我可以访问Boost和TBB库。

编辑:该队列是char类型,因为它用于速度逐字节发送消息。之前的实现是一次发送整个消息。

+0

这是读写器问题还是写作者问题? – DumbCoder

+0

作家写作。两个线程都写入队列。 –

+0

'为了速度'是什么意思?在这个实现中它会变得更慢**。 – SergeyA

回答

3

除了互斥体(或信号量或关键部分 - 实际上都是相同的东西)之外,您没有其他选择。没有其他人会确保当前设计中的非交错消息。

但是,我确实质疑当前设计的智慧。当语义是整个信息时,你为什么要有一个字符队列?将整条消息作为单个队列元素不是更好吗?

0

一个可能的解决办法可能是使用boost::lockfree::queue<std::string>

然后,您可以推及弹出整个消息,而无需进一步的同步。

如您所说,您必须使用字节,您可以尝试boost::lockfree::spsc_queue<char>。有你有会员

size_t write_available(size_t max_size) const 
size_type push(T const * t, size_type size) 

所以用互斥锁在一起,你可以写这样的事情在pushMessage方法

{ 
    boost::lock_guard<boost::mutex> guard(mutex_); 
    if(queue_.write_available(len)) 
     queue_.push(msg, len); 
} 
0

什么是最有效的方式,以保证队列 的内容做没有混合的msg?

这是我的经验(但主要是pre-C++ 11),当线程'很少'碰撞时,任何互斥信号都是'轻量级'。我从中推断出,上下文切换必须是高成本的行为。如果临界区被“解锁”,互斥检查的成本很小。

通常,我使用(并推荐)互斥锁,然后跟进测试以查看行为是否足够。

一个或许比较有用

一)多少次一个线程进入一个互斥锁保护临界区(即没有竞争)

VS

二)有多少线程使用相同的互斥执行时,上下文切换就可以完成。

+0

在我的ubuntu15.10上,g ++ 5.2.1,未优化和旧的Dell hw,a)std :: mutex lock()和unlock()大约需要47纳秒b)使用C++-11线程切换std :: mutex大约需要12,000纳秒。 –