首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UDP -微突发期间丢失的数据

UDP -微突发期间丢失的数据
EN

Stack Overflow用户
提问于 2011-07-13 03:44:00
回答 4查看 675关注 0票数 2

下面的代码运行得很好(即。不会丢弃消息) 99.9的概率。但是,当数据报之间以2-3微秒的速度出现微突发数据报时,我就会遇到数据丢失。boost notify_one()成员调用需要5到10微秒才能完成,因此它本身就是这些条件下的关键瓶颈。对如何提高性能有什么建议吗?

接收者/“生产者”代码线程:

代码语言:javascript
复制
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
}

消费者代码线程:

代码语言:javascript
复制
//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);
}
EN

回答 4

Stack Overflow用户

发布于 2011-07-13 04:11:49

只要改变就好

代码语言:javascript
复制
if (!InQ.msg_queue.empty()) {

代码语言:javascript
复制
while (!InQ.msg_queue.empty()) {

这样,数据包就不必唤醒线程来进行处理,如果线程已经唤醒和忙碌,它将在休眠之前看到新的数据包。

好吧,这并不是那么简单,因为您需要释放数据包之间的锁,但是这个想法是可行的--在睡眠之前,检查队列是否为空。

票数 2
EN

Stack Overflow用户

发布于 2011-07-13 03:50:13

如果您正在丢失数据,请尝试增加套接字缓冲区读取大小。如果您使用的是boost::asio,请查看此选项:boost::asio::socket_base::receiver_buffer_size。通常,对于高吞吐量的UDP应用程序,我们将套接字缓冲区大小设置为1MB (在某些情况下会更大)。

此外,请确保您在接收调用中使用的缓冲区不会太大,它们应该仅足以处理您的最大预期数据报大小(这显然取决于实现)。

票数 1
EN

Stack Overflow用户

发布于 2011-07-13 03:58:30

你明显的障碍在调理中。你的主要希望是使用一个无锁的Q实现。这对你来说可能是一句显而易见的话。当然,让无锁Q真正为你工作的唯一方法是,如果你有多核,并且不介意专注于消耗任务。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6670103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档