C++ 中的并发效率

Concurrency efficiency in C++

我有一个函数pushMessage()

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 类型的,因为它用于逐字节发送消息,以提高速度。以前的实现是一次发送整个消息。

除了互斥量(或信号量或临界区 - 实际上都是一样的),您别无选择。在当前设计中,没有其他方法可以确保非交错消息。

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

一个可能的解决方案是使用 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 );
}

What's the most efficient way to ensure that the contents of the queue do not have a mix of concurrent msg?

根据我的经验(但主要是 c++11 之前的版本),当线程 'seldom' 发生冲突时,任何互斥信号量都是 'light duty'。我由此推断上下文切换一定是高成本的动作。如果临界区是'unlocked',互斥检查的开销很小。

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

一个可能有用的比较

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

对比

b) 当使用相同的互斥锁强制执行时,可以完成多少线程上下文切换。