GCD 调度源和 select() 有什么区别?

发布于 2024-09-28 10:48:08 字数 675 浏览 4 评论 0原文

我一直在编写一些代码来替换一些现有的:

while(runEventLoop){
  if(select(openSockets, readFDS, writeFDS, errFDS, timeout) > 0){
    // check file descriptors for activity and dispatch events based on same 
  }
} 

套接字读取代码。我想将其更改为使用 GCD 队列,以便我可以使用dispatch_async 将事件弹出到队列中,而不是维护“必须在下一次迭代时调用”数组。我也已经在使用 GCD 队列来/包含/这个特定的操作,因此希望将其转变成更自然的 GCD 调度形式。 (不是 while() 循环独占串行队列)

但是,当我尝试将其重构为依赖于从绑定到套接字描述符上的 DISPATCH_SOURCE_TYPE_READ 和 DISPATCH_SOURCE_TYPE_WRITE 的事件处理程序激发的调度源的形式时,依赖于此调度的库代码停止工作了。我的第一个假设是我误解了 DISPATCH_SOURCE_TYPE_READ 和 DISPATCH_SOURCE_TYPE_WRITE 的使用 - 我假设它们会产生与使用这些套接字描述符调用 select() 大致相同的行为。

我是否误解了 GCD 调度来源?或者,关于重构,我是否在不太适合的情况下使用它?

I've been writing some code that replaces some existing:

while(runEventLoop){
  if(select(openSockets, readFDS, writeFDS, errFDS, timeout) > 0){
    // check file descriptors for activity and dispatch events based on same 
  }
} 

socket reading code. I'd like to change this to use a GCD queue, so that I can pop events on to the queue using dispatch_async instead of maintaining a "must be called on next iteration" array. I also am already using a GCD queue to /contain/ this particular action, hence wanting to devolve it to a more natural GCD dispatch form. ( not a while() loop monopolizing a serial queue )

However, when I tried to refactor this into a form that relied on dispatch sources fired from event handlers tied to DISPATCH_SOURCE_TYPE_READ and DISPATCH_SOURCE_TYPE_WRITE on the socket descriptors, the library code that depended on this scheduling stopped working. My first assumption is that I'm misunderstanding the use of DISPATCH_SOURCE_TYPE_READ and DISPATCH_SOURCE_TYPE_WRITE - I had assumed that they would yield roughly the same behavior as calling select() with those socket descriptors.

Do I misunderstand GCD dispatch sources? Or, regarding the refactor, am I using it in a situation where it is not best suited?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

朱染 2024-10-05 10:48:08

对你的问题的简短回答是:没有。没有区别,GCD 调度源和 select() 都做同样的事情:它们通知用户发生了特定的内核事件或特定的条件成立。

请注意,在 Mac 或 iOS 设备上,您不应使用 select(),而应使用更高级的 kqueue()kevent() (或kevent64())。

您当然可以将代码转换为使用 GCD 调度源,但您需要小心,不要破坏依赖于此的其他代码。因此,这需要对处理信号、文件描述符、套接字和所有其他低级内核事件的整个代码进行完整检查。

可能更简单的解决方案是维护原始代码,只需在对事件做出反应的部分中添加 GCD 代码即可。在这里,您可以根据事件的特定类型将事件分派到不同的队列上。

The short answer to your question is: none. There are no differences, both GCD dispatch sources and select() do the same thing: they notify the user that a specific kernel event happened or that a particular condition holds true.

Note that, on a mac or iOS device you should not use select(), but rather the more advanced kqueue() and kevent() (or kevent64()).

You may certainly convert the code to use GCD dispatch sources, but you need to be careful not to break other code relying on this. So, this needs a complete inspection of the whole code handling signals, file descriptors, socket and all of the other low level kernel events.

May be a simpler solution could be to maintain the original code, simply adding GCD code in the part that react to events. Here, you dispatch events on different queues depending on the particular type of event.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文