问题陈述:
我有一个生产者消费者线程共享共享数据,这只是一个结构。 消费者线程正在等待std :: condition变量wait。生产者线程recvs包写下共享结构并通知消费者线程。
挑战:消费者线程必须以几毫秒(比如10-15ms)处理和发送响应。
问题 - 在一段时间内,有很少的时间,线程本身需要时间从cv等待唤醒,因此无法在几毫秒内响应。
我尝试使用yield,但这会占用cpu,并且要求cpu利用率应尽可能保持最低。
我有兴趣知道: 1 - 为什么线程花了这么多时间才醒来.. ?? (在某些情况下超过40毫秒)。 2 - 有没有其他方法可以在线程之间共享数据而不允许线程休眠并且还使用最小的cpu。(尝试使用管道,但在当前共享内存实现上的性能较低)。
3 - 建议任何其他可能不包括线程的设计仍然单独关注并实现所需的延迟.. ????
这是共享数据:
class Message
{
typedef std::basic_string<uint8_t> MesgBuffType;
MesgBuffType _buffer;
static uint16_t _data[256];
public :
append(data .....,len ) append methods
}
void ProcessData(Messege msg)
{
std::unique_lock<std::mutex> lock(mutex);
sharedData.set(msg);
lock.unlock();
_syncCondVar.notify_one();
}
void consumeData()
{
std::unique_lock<std::mutex> lock(mutex);
_syncCondVar.wait(lock);
Messege req;
if (sharedData.get(req))
{
lock.unlock();
processRequest(req);
}
}
添加了支持代码。
答案 0 :(得分:3)
1 - 为什么线程花了这么多时间才醒来.. ?? (在某些情况下超过40毫秒)。
没有看到代码就无法说出来。也许你不会在生产者线程中尽快释放互斥锁,或者结构可能是生成器线程一直写入的缓存行,并且消费者必须反复重新读取缓存行,或者其他可能的东西完全。由于缺乏信息,您的问题应该被关闭。
2 - 有没有其他方法可以在线程之间共享数据而不允许线程休眠并且还使用最小的cpu。(尝试使用管道,但在当前共享内存实现方面的性能较低)。
使用原子或无锁结构,但它们很难正确使用。
3 - 建议任何其他可能不包括线程的设计仍然单独关注并实现所需的延迟.. ????
单线程,基于事件的模型通常比多线程模型具有更低的延迟,主要是因为线程之间没有上下文切换,也不需要同步对数据的访问。
答案 1 :(得分:1)
代码似乎没有正确使用条件变量:即使有新数据可用,您也无条件地等待条件变量。这就是你观察漫长等待时间的原因。
条件变量是无状态的:它们不记得错过的通知。你也可以得到虚假的叫醒声。这就是为什么某些状态必须与条件变量相关联并且必须在循环中进行等待的原因,有关详细信息,请参阅std::condition_variable::wait
。
您可能希望将更新顺序计数器与邮件更新相关联以解决此问题,例如:
<application>
答案 2 :(得分:-1)
代码中的生产者在notify_one之前解锁。 有关保持/释放锁定的性能问题,请参阅Do I have to acquire lock before calling condition_variable.notify_one()?。如果您不在生产者中使用锁定,请参阅Sync is unreliable using std::atomic and std::condition_variable了解罕见的案例竞争条件。如果你想在生产者中保持锁定,或者不使用锁定来提高性能,请阅读并证明其合理性。