2012-11-20 2 views
23

Ich habe eine lange laufende Funktion innerhalb einer asynchronen (seriellen) Worker-Warteschlange. Ich weiß, dass diese Funktion manchmal in einem bestimmten openCV-Aufruf hängt. Aus diesem Grund verursacht dieser Hang auch das Hängen des Hauptthreads. Wenn das Anhalten und Debug-Modus Eingabe Ich sehe, dass es einen Anruf zuIOS semaphore_wait_trap auf Haupt-Thread verursacht Hang in UI

ist
semaphore_wait_trap() 

auf dem Hauptthread (Queue)

ich den hängenden Faden aussetzen kann (My Arbeiter Warteschlange) im Debug-Modus und dann diese Trap verschwindet und die GUI reagiert wieder auf das Telefon.

Nachdem der Arbeitsthread wieder freigegeben wurde, reagiert die GUI für 1-2 Sekunden (ich vermute, bis dieser Thread wieder aktiviert wird) und dann reagiert die Benutzeroberfläche nicht mehr.

Dieser Thread macht keine dispatch_sync() Anrufe an den Haupt-Thread/Queue

Ist es möglich, dass IOS den Haupt-Thread pausiert („Fallen“ es), weil die Arbeiter lange läuft?

Kann ich es zwingen, den Block zu entfernen ??

Ich füge einige Druckbildschirme des Debug-Modus-Stacks hinzu.

Bevor die Hänge Queue Aussetzung:

Main Queue Stack

Und das hängende thread:

Hanging Queue

Und nach einer Pause und zur Aussetzung der schlechten Warteschlange:

After Suspending

+0

Ist "pixtr" Sie oder ein Produkt eines Drittanbieters? . Wenn seine dritte Partei würde ich in Betracht ziehen, es von Ihrer UI zu lösen, um zu sehen, ob das das Problem ist –

+0

Es gibt nicht viel, um hier weiterzugehen (insbesondere weiß ich nicht, was in 'add_blob' ist), also ist das Beste, was ich habe, Vermutungen . Mein Verdacht ist, dass Sie falsche Flags an 'cvFloodFill' übergeben und dies dazu führt, dass es aufhört, die GPU zu sperren. Da UIKit auch die GPU benötigt, um Scrolling zu berechnen (DYTransport ist ein privates Framework für die GPU-Berechnung), hängt dies daran, dass UIKit darauf wartet, dass die GPU verfügbar wird. –

Antwort

2

Ist es möglich, dass IOS den Haupt-Thread pausiert ("abfängt"), weil der Arbeiter lange läuft? - NEIN. Ich denke, Ihr Problem hängt mit dem Zeichnen oder Ändern einiger UI-Elemente zusammen. Nicht alle Funktionen können vom Hintergrundthread aufgerufen werden (z. B. müssen Änderungen an UI-Elementen im Hauptthread vorgenommen werden). In der Serien Warteschlange, wenn jede Methode UI-Elemente geändert werden muss, müssen Sie es auf Hauptthread zB zu behalten vergessen Sie rufen

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

Ich mache keine Anrufe von der Hintergrund-Worker-Thread. –

+0

Ich mache dispatch_queue_create ("worker_queue", DISPATCH_QUEUE_SERIAL); –

+0

dispatch_async (meine_warteschlange, {Workerblock mit Rückruf bei Beendigung}) –

0

Vielleicht nur eine Variable in Call Dispatch-Funktion (Was mich betrifft war ich weggelassen ein static Schlüsselwort vor Dispatch_once_t Deklaration und Versand kann nicht mit Inline-Funktion verarbeitet werden). Die Stack-Spur war genau wie deine. Das war meine Schuld.

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