IOS semaphore_wait_trap on main thread causing han

2019-01-25 03:02发布

问题:

I have a long running function inside an asynchronous (serial) worker queue. I know that sometimes this function hangs inside a particular openCV call. For some reason this hang is also causing the main thread to hang. When pausing and entering debug mode I see that there is a call to

semaphore_wait_trap()

on the main thread (Queue)

I can suspend the hanging thread (My worker queue) in debug mode and then this trap goes away and the GUI becomes responsive once again on the phone.

After unpausing the worker thread the GUI is responsive for 1-2 seconds (I suspect until this thread is activated again) and then the UI becomes unresponsive once again.

This thread makes no dispatch_sync() calls to the main thread/Queue

Is it possible that IOS pauses the main thread ("traps" it) because the worker is long running?

Can I force it to remove the block??

I am adding some print screens of the debug mode stack.

Before suspending the hanging Queue:

And the hanging thread:

And After Pausing and suspending the bad queue:

回答1:

Is it possible that IOS pauses the main thread ("traps" it) because the worker is long running? - NO. I think, your problem is related to drawing or changing some UI elements. Not all functions can be called from background thread (e.g. changes to UI elements has to be done in main thread.). In your serial queue, if any method needs to change UI elements, you have to call it on main thread e.g

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


回答2:

Maybe you just forgot to retain a variable into dispatch function call (As for me I was omitted a static keyword before dispatch_once_t declaration and dispatch can't process with inline function). The stack trace was just like yours. That was my fault.

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