GCD Dispatch Sources和select()有什么区别?

时间:2010-10-21 12:59:20

标签: iphone ios multithreading sockets grand-central-dispatch

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

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调度来源?或者,关于重构,我是否在最不合适的情况下使用它?

1 个答案:

答案 0 :(得分:3)

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

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

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

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