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) 当使用相同的互斥锁强制执行时,可以完成多少线程上下文切换。
我有一个函数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) 当使用相同的互斥锁强制执行时,可以完成多少线程上下文切换。