2011-07-27 4 views
9

私はキューを使い慣れていません。以下のスキームを設定する際にいくつか問題があります。さまざまなディスパッチキューのタスクを同期させる方法は?

私には3つのタスクがあります。

タスクA:メインキューでのみ実行できます。タスクBと非同期で実行でき、タスクCと非同期で実行できません。実行頻度は高くなりますが、かなり速く実行されます。

タスクB:任意のキューで実行できます。タスクAと非同期で実行できます。タスクCと非同期に実行できません。実行はまれですが、実行には時間がかかります。後で実行するにはタスクCが必要ですが、タスクCはタスクAと非同期には実行できません。

タスクC:任意のキューで実行できます。タスクAまたはタスクBのいずれとも非同期で実行できません。実行はめったになく、すぐに実行されます。

今私はこのようにそれを持っている:

タスクAは、シリアルキューX(タスクがメインキューにタスクAを提出するシリアルキューXに提出された)によってメインキューに送信されます。

タスクCがちょうどタスクA

のようにここでの問題は、タスクCが時々で実行されることで、シリアルキューXでメインキューに提出され

タスクBがシリアルキューXに提出されますメインキューは、シリアルキューがタスクBを実行するのと同時にタスクCを実行することがあります。

したがって、タスクBとタスクCが同時に実行されることはありませんAとBが同時に実行され、AとCが同時に実行されないようにしますか?さらに、彼らは同じ回数を実行することを確認するための簡単な方法はありますか? (前後に交互に)

答えて

2

私はGREでこの問題を抱えていたと思います.A、B、CだけがBob、Larry、Sueであり、彼らはすべて同じオフィスで働いていました。

これは、シリアルキューとディスパッチセマフォの組み合わせで解決できると思います。単一ワイド・シリアル・ディスパッチ・キューをセットアップしてタスクBとCをそれにサブミットすると、それらが同時に実行されないことが保証されます。その後、タスクAとCの間で共有されるカウントが1に設定されたディスパッチセマフォを使用して、それらのうちの1つだけが一度に実行されることを保証できます。私はそのようなセマフォーが私の答えhereでどのように機能するか説明します。 DISPATCH_TIME_FOREVERを使用するようにそのコードを変更する必要があるかもしれません。そのため、タスクAは、Cが実行されている場合(Cの提出の場合と同様に)、投げられる前に押さえつけられます。

このように、AとBは異なるキュー(メインキューとシリアルキュー)で実行されるように並列で実行できますが、BとCは共有キューによって同時に実行できません。 AとCはセマフォのためです。

AとCのロードバランシングについては、バランスのとれたアプリケーションといえども、かなりのアプリケーション固有のものになるでしょう。サイクルを無駄にする。私はまた、あなたが本当にそれらを均等に交互にする必要があるかどうか、あるいはあなたが少しずつ走っていくことができるかどうかを確かめたいと思います。

+0

パーフェクト、それはまさに私がする必要があったものです。本当にありがとう! – Randall

0

操作を同期するためにNSOperationをチェックしましたか?そこに依存関係を扱うことができます。

0

もちろん、Cは常にAとBを従わなければならないと仮定すると、AとBは自分の操作の完了コールバックとしてCをスケジュールする必要があります(Cはそれがまだないことを確認します) AとBの両方が同時に起こることを要求した場合に実行する)。完了コールバックパターン(dispatch_asyncのmanページで説明)は非常に強力で、それにもかかわらず結合される必要がある非同期操作を直列化する優れた方法です。

ADが非同期で実行できるE、B、C、D、Eの問題があり、Eが常に最後に実行される必要がある場合は、Eを完了コールバックとして実行するように設定できるため、そのグループにAEを入れるだけです。

関連する問題