下面的代码运行得很好(即。不会丢弃消息) 99.9的概率。但是,当数据报之间以2-3微秒的速度出现微突发数据报时,我就会遇到数据丢失。boost notify_one()成员调用需要5到10微秒才能完成,因此它本身就是这些条件下的关键瓶颈。对如何提高性能有什么建议吗?
接收者/“生产者”代码线程:
if (bytes_recvd > 0) {
InQ.mut.lock();
string t;
t.append(data_, bytes_recvd);
InQ.msg_queue.push(t); // < 1 microsecs
InQ.mut.unlock();
InQ.cond.notify_one(); // 5 - 10 microsecs
}消费者代码线程:
//snip......
std::string s;
while (1) {
InQ.mut.lock();
if (!InQ.msg_queue.empty()) {
s.clear();
s = InQ.msg_queue.front();
InQ.msg_queue.pop();
}
InQ.mut.unlock();
if (s.length()) {
processDatagram((char *)s.c_str(), s.length());
s.clear();
}
boost::mutex::scoped_lock lock(InQ.mut);
InQ.cond.wait(lock);
}发布于 2011-07-13 04:11:49
只要改变就好
if (!InQ.msg_queue.empty()) {至
while (!InQ.msg_queue.empty()) {这样,数据包就不必唤醒线程来进行处理,如果线程已经唤醒和忙碌,它将在休眠之前看到新的数据包。
好吧,这并不是那么简单,因为您需要释放数据包之间的锁,但是这个想法是可行的--在睡眠之前,检查队列是否为空。
发布于 2011-07-13 03:50:13
如果您正在丢失数据,请尝试增加套接字缓冲区读取大小。如果您使用的是boost::asio,请查看此选项:boost::asio::socket_base::receiver_buffer_size。通常,对于高吞吐量的UDP应用程序,我们将套接字缓冲区大小设置为1MB (在某些情况下会更大)。
此外,请确保您在接收调用中使用的缓冲区不会太大,它们应该仅足以处理您的最大预期数据报大小(这显然取决于实现)。
发布于 2011-07-13 03:58:30
你明显的障碍在调理中。你的主要希望是使用一个无锁的Q实现。这对你来说可能是一句显而易见的话。当然,让无锁Q真正为你工作的唯一方法是,如果你有多核,并且不介意专注于消耗任务。
https://stackoverflow.com/questions/6670103
复制相似问题