2016-04-27 10 views
0

私は、メインスレッドがいくつかのglobal_queueタスクでビジー状態になる可能性があると言うと、グローバルキュー上のdispatch_asyncで実行されるブロックをメインスレッド上で実行することは可能ですか?

たとえば、私は実行するタスクがあり、次のステートメントのいずれかを使用します。

dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) { 
     // task 1 
    } 

// or 

    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) { 
     // task 2 
    } 

このタスクはメインスレッドで間違って取得できますか?または、メインスレッドがグローバルキューに対してロックされているため不可能ですか? ありがとうございました!

+0

試しましたか?ところで、これはバックグラウンドタスクの概念を完全に無効にします。メインスレッドはできるだけフリーにしておきます。一度にメインスレッド上で実行できるのは1つだけです。あなたの「背景」のものの一部で動いている場合、ブロックされます。それはUIを更新しません、それは入力に応答しません、そして、あまりにも長い時間がかかると、アプリケーションは殺されるでしょう。 – Eiko

+0

はい、私はそれを知っています。しかし、メインスレッドがアイドル状態の場合、global_queueからタスクを取ることができますか? –

+0

これは実装上の大きなバグであり、起こることはないと思います。 – Eiko

答えて

4

グローバルキューにディスパッチすると、グローバルキューで実行されます。メインキューにディスパッチすると、メインキューで実行されます。自分で作成したキューにディスパッチすると、そのキューで実行されます。

あなたは「メインスレッドがアイドルであれば、global_queueからタスクを取ることができますか」と尋ねました。いいえ、それは完全にその点を見逃すでしょう。メインキューがアイドル状態の場合、すべてのCPUがバックグラウンドタスクを実行できるため、バックグラウンドスレッドは少し速く実行されます。メインキューが別のキューからタスクを取得するのは無意味で間違っています。

+0

ドキュメントでサポートされていないGCDの実装についての声明を作成しており、警告なしでいつでも変更できる実装の詳細を暗示しています。 – ipmcc

+1

@ipmcc、これは基本的な並行処理です。 gnasherは正しいです。 –

+0

GCDドキュメントでは、バックグラウンドGCDキューにタスクを送信しても、コンピュータが炎に溢れてしまうことはありません。それは理解されています。 –

1

実際には起こるべきではありませんが、QOSクラスを指定してキューを取得すると、厳密に言えば実装の詳細が得られます。キューには依存しないでください特定のキューではありません)。さらに、キューにエンキューされた作業を満たすために、任意のキューが使用するスレッドはでも実装の詳細です。

実際には、いいえ、QOS_CLASS_BACKGROUNDまたはQOS_CLASS_UTILITYがメインスレッド上で実行されているエンキューされた作業は期待できません。

キューがdispatch_get_global_queue(QOS_CLASS_UTILITY, 0) == dispatch_get_main_queue()から返されているかどうかを確認し、同じようにワークユニット内で[NSThread isMainThread]をチェックして、メインスレッドで実行しているかどうかを確認できます。

+0

ありがとうございますが、これはQOS_CLASS_USER_INITIATEDやQOS_CLASS_USER_INTERACITVEのような他のQoSで起こりますか? –

+0

それは私があまり確信していませんが、たとえそれが起こっているのを見ても、実装の詳細になります。 :)簡単なテストをすると、 'QOS_CLASS_USER_INTERACTIVE'と' QOS_CLASS_USER_INITIATED'の 'dispatch_async'ブロックはメインスレッドで実行されません。 – ipmcc

+0

dispatch_get_global_queue _always_はグローバルキューを返します。それ以外は何も返しません。それは他の何かを返すために完全に台無しになるだろう。 – gnasher729

関連する問題