14

私はいくつかの既存のものを置き換えるいくつかのコードを書いています:

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

ソケット読み取りコード。これを GCD キューを使用するように変更して、「次の反復で呼び出す必要がある」配列を維持する代わりに、dispatch_async を使用してイベントをキューにポップできるようにします。また、この特定のアクションを /contain/ するために既に GCD キューを使用しているため、より自然な GCD ディスパッチ形式に委譲したいと考えています。(シリアル キューを独占する while() ループではありません)

しかし、これを、ソケット記述子の DISPATCH_SOURCE_TYPE_READ および DISPATCH_SOURCE_TYPE_WRITE に関連付けられたイベント ハンドラーから起動されるディスパッチ ソースに依存する形式にリファクタリングしようとすると、このスケジューリングに依存するライブラリ コードが機能しなくなりました。私の最初の仮定は、DISPATCH_SOURCE_TYPE_READ と DISPATCH_SOURCE_TYPE_WRITE の使用を誤解しているということです。これらのソケット記述子で select() を呼び出すのとほぼ同じ動作になると想定していました。

GCD ディスパッチ ソースを誤解していませんか? または、リファクタリングに関しては、最適ではない状況で使用していますか?

4

1 に答える 1

3

あなたの質問に対する簡単な答えは:なし。違いはありません。GCDディスパッチソースとselect()同じことを行います。特定のカーネルイベントが発生したこと、または特定の条件が当てはまることをユーザーに通知します。

select()MacまたはiOSデバイスでは、を使用するのではなく、より高度なkqueue()and kevent()(または)を使用する必要があることに注意してくださいkevent64()

確かにGCDディスパッチソースを使用するようにコードを変換することはできますが、これに依存する他のコードを壊さないように注意する必要があります。したがって、これには、コード処理信号、ファイル記述子、ソケット、およびその他すべての低レベルカーネルイベントを完全に検査する必要があります。

より簡単な解決策は、イベントに反応する部分にGCDコードを追加するだけで、元のコードを維持することかもしれません。ここでは、特定のタイプのイベントに応じて、さまざまなキューにイベントをディスパッチします。

于 2011-03-04T15:14:31.483 に答える