- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
所以我有 N 个异步的、带时间戳的数据流。每个流都有固定的速率。我想处理所有数据,但要注意的是我必须尽可能接近数据到达的时间来处理数据(这是一个实时流应用程序)。
到目前为止,我的实现是创建一个包含 K 条消息的固定窗口,我使用优先级队列按时间戳对其进行排序。然后我在移动到下一个窗口之前按顺序处理整个队列。这没关系,但它不太理想,因为它会产生与缓冲区大小成比例的滞后,并且如果消息刚好在缓冲区末尾处理完后到达,有时还会导致消息丢失。它看起来像这样:
// Priority queue keeping track of the data in timestamp order.
ThreadSafeProrityQueue<Data> q;
// Fixed buffer size
int K = 10;
// The last successfully processed data timestamp
time_t lastTimestamp = -1;
// Called for each of the N data streams asyncronously
void receiveAsyncData(const Data& dat) {
q.push(dat.timestamp, dat);
if (q.size() > K) {
processQueue();
}
}
// Process all the data in the queue.
void processQueue() {
while (!q.empty()) {
const auto& data = q.top();
// If the data is too old, drop it.
if (data.timestamp < lastTimestamp) {
LOG("Dropping message. Too old.");
q.pop();
continue;
}
// Otherwise, process it.
processData(data);
lastTimestamp = data.timestamp;
q.pop();
}
}
关于数据的信息:它们保证在它们自己的流中被排序。它们的频率在 5 到 30 赫兹之间。它们由图像和其他数据组成。
为什么这比看起来更难的一些例子。假设我有两个流,A 和 B 都以 1 Hz 的频率运行,并且我按以下顺序获取数据:
(stream, time)
(A, 2)
(B, 1.5)
(A, 3)
(B, 2.5)
(A, 4)
(B, 3.5)
(A, 5)
看看如果我按接收数据的顺序处理数据,B 会如何总是被丢弃?这正是我想要避免的。现在在我的算法中,B 会每 10 帧被丢弃,我会处理过去 10 帧延迟的数据。
最佳答案
我建议使用生产者/消费者结构。让每个流将数据放入队列,并让一个单独的线程读取队列。即:
// your asynchronous update:
void receiveAsyncData(const Data& dat) {
q.push(dat.timestamp, dat);
}
// separate thread that processes the queue
void processQueue()
{
while (!stopRequested)
{
data = q.pop();
if (data.timestamp >= lastTimestamp)
{
processData(data);
lastTimestamp = data.timestamp;
}
}
}
这可以防止您在处理批处理时在当前实现中看到的“滞后”。
processQueue
函数在一个单独的持久线程中运行。 stopRequested
是程序在要关闭时设置的标志——强制线程退出。有些人会为此使用 volatile
标志。我更喜欢使用手动重置事件之类的东西。
要完成这项工作,您需要一个允许并发更新的优先级队列实现,或者您需要用同步锁包装您的队列。特别是,您要确保 q.pop()
在队列为空时等待下一个项目。或者当队列为空时,您永远不会调用 q.pop()
。我不知道您的 ThreadSafePriorityQueue
的具体细节,所以我无法确切地说出您将如何编写它。
时间戳检查仍然是必要的,因为有可能在较早的项目之前处理较晚的项目。例如:
processQueue
函数从队列中移除。这并不罕见,只是很少见。时间差通常为微秒级。
如果您经常无序地获取更新,那么您可以引入人为延迟。例如,在您更新的问题中,您显示的消息以 500 毫秒的顺序乱序出现。假设 500 毫秒是您要支持的最大容差。也就是说,如果消息延迟超过 500 毫秒,它将被丢弃。
您所做的是在将事物添加到优先级队列时向时间戳添加 500 毫秒。即:
q.push(AddMs(dat.timestamp, 500), dat);
在处理事物的循环中,您不会在时间戳之前使事物出列。像这样的东西:
while (true)
{
if (q.peek().timestamp <= currentTime)
{
data = q.pop();
if (data.timestamp >= lastTimestamp)
{
processData(data);
lastTimestamp = data.timestamp;
}
}
}
这会在所有项目的处理中引入 500 毫秒的延迟,但它可以防止丢弃落在 500 毫秒阈值内的“延迟”更新。您必须在对“实时”更新的期望与防止丢失更新的期望之间取得平衡。
关于对 N 个数据流进行时间排序的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44949899/
我正在尝试对每个条目有多个值的关联数组进行排序。 例如 [0] => stdClass Object ( [type] => node [sid] => 158 [score] => 0.059600
我在 mysql 中有“日期”列以这种格式保存日期 2014 年 9 月 17 日(日-月-年) 我需要对它们进行升序排序,所以我使用了这个命令: SELECT * FROM table ORDER
我目前正在将 MySQL 存储过程重写为 MS SQL 存储过程,但遇到了问题。 在 MySQL 存储过程中,有一个游标,它根据最近的日期 (effdate) 选择一个值并将其放入变量 (thestt
我想要 gwt r.QuestionId- 排序。但是我得到未排序的 QuestionId 尽管我提到了 QuestionId ASC 的顺序。 SELECT r.QuestionId,
我有一个关于在 scandir 函数中排序的基本问题。到目前为止,我阅读了 POSIX readdir 的手册页,但没有找到有关订购保证的具体信息。 但是当我遍历大目录(无法更改,只读)时,我在多个系
基本上我必须从 SQL 数据库中构建项目列表,但是用户可以选择对 7 个过滤器的任意组合进行过滤,也可以选择要排序的列以及按方向排序。 正如您可以想象的那样,这会以大量不同的组合进行编码,并且数据集非
我有两张 table 。想象第一个是一个目录,包含很多文件(第二个表)。 第二个表(文件)包含修改日期。 现在,我想选择所有目录并按修改日期 ASC 对它们进行排序(因此,最新的修改最上面)。我不想显
我想先根据用户的状态然后根据用户名来排序我的 sql 请求。该状态由 user_type 列设置: 1=活跃,2=不活跃,3=创始人。 我会使用此请求来执行此操作,但它不起作用,因为我想在“活跃”成员
在 C++ 中,我必须实现一个“类似 Excel/Access”(引用)的查询生成器,以允许对数据集进行自定义排序。如果您在 Excel 中使用查询构建器或 SQL 中的“ORDER BY a, b,
我面临这样的挑战: 检索按字段 A 排序的文档 如果字段 B 存在/不为空 . 否则 按字段排序 C. 在 SQL 世界中,我会做两个查询并创建一个 UNION SELECT,但我不知道如何从 Mon
我想对源列表执行以下操作: map 列表 排序 折叠 排序 展开 列表 其中一些方法(例如map和toList)是可链接的,因为它们返回非空对象。但是,sort 方法返回 void,因为它对 List
我制作了一个用于分析 Windows 日志消息编号的脚本。 uniq -c 数字的输出很难预测,因为根据数字的大小会有不同的空白。此时,我手动删除了空白。 这是对消息进行排序和计数的命令: cat n
我有以下词典: mydict1 = {1: 11, 2: 4, 5: 1, 6: 1} mydict2 = {1: 1, 5: 1} 对于它们中的每一个,我想首先按值(降序)排序,然后按键(升序)排序
我刚刚开始使用泛型,目前在对多个字段进行排序时遇到问题。 案例: 我有一个 PeopleList 作为 TObjectList我希望能够通过一次选择一个排序字段,但尽可能保留以前的排序来制作类似 Ex
有没有办法在 sql 中组合 ORDER BY 和 IS NULL 以便我可以在列不为空时按列排序,但如果它为null,按另一列排序? 最佳答案 类似于: ORDER BY CASE WHEN
我有一个包含 2 列“id”和“name”的表。 id 是常规的自动增量索引,name 只是 varchar。 id name 1 john 2 mary 3 pop 4 mary 5 j
场景 网站页面有一个带有分页、过滤、排序功能的表格 View 。 表中的数据是从REST API服务器获取的,数据包含数百万条记录。 数据库 REST API 服务器 Web 服务器 浏览器 问
假设我有一本字典,其中的键(单词)和值(分数)如下: GOD 8 DONG 16 DOG 8 XI 21 我想创建一个字典键(单词)的 NSArray,首先按分数排序,然后按字
如何在 sphinx 上通过 sql 命令选择前 20 行按标题 WEIGHT 排序,接下来 20 行按标题 ASC 排序(总共 40 个结果),但不要给出重复的标题输出。 我尝试了这个 sql 命令
我有一个奇怪的问题,当从 SQLite 数据库中选择信息并根据日期排序时,返回的结果无效。 我的SQL语句是这样的: Select pk from usersDates order by dateti
我是一名优秀的程序员,十分优秀!