web-dev-qa-db-ja.com

IOSメインスレッドのsemaphore_wait_trapがUIのハングを引き起こしている

非同期(シリアル)ワーカーキュー内に長時間実行される関数があります。この関数が特定のopenCV呼び出し内でハングすることがあることを私は知っています。何らかの理由で、このハングによりメインスレッドもハングします。一時停止してデバッグモードに入ると、への呼び出しがあることがわかります

_semaphore_wait_trap()
_

メインスレッド(キュー)

ハングしているスレッド(マイワーカーキュー)をデバッグモードで一時停止すると、このトラップがなくなり、GUIが電話で再び応答するようになります。

ワーカースレッドの一時停止を解除した後、GUIは1〜2秒間応答し(このスレッドが再びアクティブになるまでは疑わしい)、その後UIは再び応答しなくなります。

このスレッドは、メインスレッド/キューに対してdispatch_sync()呼び出しを行いません。

ワーカーが長時間実行されているためにIOSがメインスレッドを一時停止(「トラップ」)する可能性はありますか?

ブロックを強制的に削除できますか?

デバッグモードスタックのいくつかの印刷画面を追加しています。

ハングしているキューを一時停止する前に:

Main Queue Stack

そしてぶら下がっている糸:

Hanging Queue

そして、不良キューを一時停止および一時停止した後:

After Suspending

24
Avner Barr

ワーカーが長時間実行されているためにIOSがメインスレッドを一時停止(「トラップ」)する可能性はありますか?-いいえ。問題は一部のUI要素の描画または変更に関連していると思います。すべての関数はバックグラウンドスレッドから呼び出すことができます(たとえば、UI要素の変更はメインスレッドで行う必要があります)。シリアルキューでは、UI要素を変更する必要があるメソッドがある場合は、メインスレッドで呼び出す必要があります。

dispatch_async(dispatch_get_main_queue(), ^{
                //do some main thread job here
            });
)
2
Fahri Azimov

ディスパッチ関数呼び出しに変数を保持するのを忘れただけかもしれません(私はdispatch_once_t宣言の前に静的キーワードが省略され、ディスパッチはインライン関数で処理できません)。スタックトレースはあなたと同じでした。それが私のせいでした。

+ (instancetype)sharedInstance
{
    (static was omitted) dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
} 
0
user2992955