2016-08-08 29 views
1

Leute fragen what is the way to run task in an thread. Eine der von vielen Leuten akzeptierten Antwort (vom Link) ist GCD zu verwenden.Aufgabe in die Warteschlange verschicken, um die Aufgabe in einem anderen Thread auszuführen

So habe ich versucht, auf diese Weise durch Thread-ID ausdrucken, um zu sehen, ob die Aufgabe wirklich in einem anderen Thread, nachdem sie in GCD-Warteschlange gestellt wird ausgeführt:

// a function in MyService class  
- (void) doTask { 
     NSLog(@"start do task on thread = %@", [NSThread currentThread]); 
     dispatch_queue_t queue = dispatch_queue_create("com.company.myqueue", DISPATCH_QUEUE_SERIAL); 
     dispatch_sync(queue, ^{ 
      NSLog(@"execute task on thread = %@", [NSThread currentThread]); 
     }); 
    } 

Ich betreiben:

// this is not main thread [myService doTask]

diese

Die Konsolenausgabe ist:

start do task on thread = <NSThread: 0x15b4be00>{number = 6, name = (null)} 
execute task on thread = <NSThread: 0x15b4be00>{number = 6, name = (null)} 

Es sieht Wenn die Aufgabe NICHT in einem anderen Thread ausgeführt wird, befindet sie sich im selben Thread wie der Thread des Aufrufers. Versteh ich etwas falsch? Warum führt GCD die Aufgabe nicht in einem separaten Thread aus, aber viele pepole akzeptieren die Antwort in diesem Link?

+0

Wenn Sie dispatch_async verwenden sie in einem anderen Thread ausgeführt. –

Antwort

1

GCD optimiert, wenn es möglich ist. Das synchrone Ausführen eines Blocks erfordert niemals das Wechseln von Threads, mit der einzigen Ausnahme, dass es in die Hauptwarteschlange gesendet wird, da diese auf dem Hauptthread ausgeführt werden muss.

0

Versuchen Sie unter Code, den ich von der Accepted answer genommen habe, die Sie in Ihrer Frage erwähnt haben.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    // Add code here to do background processing 
    // 

    NSLog(@"start do task on thread = %@", [NSThread currentThread]); 


    dispatch_async(dispatch_get_main_queue(), ^{ 
     // Add code here to update the UI/send notifications based on the 
     // results of the background processing 

     NSLog(@"execute task on thread = %@", [NSThread currentThread]); 
    }); 
}); 

Es wird beide verschiedenen Thread drucken. In Ihrem Testfall, den Sie in Ihre Frage eingegeben haben, ist Thread gleich und es ist synchronous Ansatz. Es wird also der gleiche Thread gedruckt. Es ist sehr weit gefasst, hier alles zu erklären. Sie sollten sich beziehen Apple Documentation for GCD.

Dokumente Staaten etwa dispatch_sync,

Sendet einen Block zu einer Absende-Warteschlange für eine synchrone Ausführung. Im Gegensatz zu dispatch_async kehrt diese Funktion erst zurück, wenn der Block beendet wurde. Der Aufruf dieser Funktion und die Ausrichtung auf die aktuelle Warteschlange führt zu einem Deadlock.

Im Gegensatz zu dispatch_async wird in der Zielwarteschlange kein Retain durchgeführt. Da Aufrufe an diese Funktion synchron sind, "leiht" sie die Referenz des Aufrufers. Darüber hinaus wird keine Block_copy am Block ausgeführt.

> Als eine Optimierung ruft diese Funktion den Block auf dem aktuellen Thread auf, wenn möglich.

0

prüfen diese

https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/dispatch_get_global_queue.3.html

Er sagt, dass

Queues nicht auf einen bestimmten Thread der Ausführung gebunden sind und an unabhängige Warteschlangen eingereicht Blöcke können gleichzeitig ausgeführt werden.

So Thread-Auswahl der Durchführung Aufgabe wird durch Thread ziehen Algorithmen von Versand lib entscheiden.aber es gibt Garantien, dass die Ausführung der Warteschlangen erfolgt durch die angegebene Konfiguration der Warteschlange (seriell oder gleichzeitig und andere)