gpt4 book ai didi

iOS select 与 kqueue/kevent 与 mach_wait_until 调度

转载 作者:行者123 更新时间:2023-12-01 15:51:46 28 4
gpt4 key购买 nike

我有一个监听单个 UDP 套接字的线程,但也需要偶尔唤醒以执行其他任务。这些任务由时间的流逝或其他线程上的事件触发。我目前的设计是使用 select() 超时值作为调度定时器,当我需要从另一个线程唤醒它时,将数据包写入套接字(环回)地址。

但是,Apple 文档说 select() 超时不应用于每秒唤醒超过几次。而且,在实践中,我发现它们可能会延迟 100 毫秒或更多,而我想要 10-20 毫秒的分辨率。他们只是试图阻止 cpu 密集型轮询,还是使用 select() 本身有问题。有没有更好的方法?

用 kqueue/kevent 替换 select 会有帮助吗?或者,创建一个专门的调度线程,用mach_wait_until()来处理定时器,然后写入套接字来唤醒网络线程?或者,在专用线程中完成所有工作,并让网络线程对传入数据进行排队?

最佳答案

这种方法让我有些困扰。为什么在 select() 线程上发生任何事情?

如果您需要一个专用于等待传入数据包的线程,它们会尽可能让该线程处于等待状态。

while (1) {
int numsockets = select(…);
if (numsockets > 0) {
// Read data (only drain the socket)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Process data
});
}
}

然后您可以使用 timer dispatch sources 运行周期性任务.

dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));

dispatch_source_set_event_handler(source, ^{
// Periodic process data
});

uint64_t nsec = 0.001 * NSEC_PER_SEC;
dispatch_source_set_timer(source, dispatch_time(DISPATCH_TIME_NOW, nsec), nsec, 0);
dispatch_resume(source);

我不知道,但有人告诉我您甚至可以使用调度源来替换 select()。

关于iOS select 与 kqueue/kevent 与 mach_wait_until 调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19128612/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com