1

Im Prinzip führt eine serielle DispatchQueue die übertragenen Aufgaben nacheinander aus. Was aber, wenn ein Kontextwechsel in einer Task ausgelöst wird (z. B. durch Aufruf von sleep)? Führt die Warteschlange die nächste Aufgabe sofort aus oder wartet auf die Beendigung der aktuellen Aufgabe?Was passiert, wenn in einer seriellen DispatchQueue ein Kontextwechsel ausgelöst wird?

Für diesen Code:

q.async { 
    print("IN 1") 
    var i = 1 
    while i < 10 { 
    Thread.sleep(forTimeInterval: 0.1) 
    i += 1 
    } 
    print("OUT of 1") 
} 

q.async { 
    print("IN 2") 
} 

ist das Ergebnis:

// IN 1 -> OUT of 1 -> IN 2 ? 
// or IN 1 -> IN 2 -> OUT of 1 ? 

ich den Code in Spielplatz versucht laufen, aber es scheint sleep (und Thread.sleep) funktioniert nicht innerhalb Spielplatz.

Antwort

0

Im Prinzip führt eine serielle DispatchQueue die übertragenen Aufgaben nacheinander aus. Was passiert aber, wenn ein Kontextwechsel in einer Task ausgelöst wird (z. B. beim Aufrufen von Sleep)? Führt die Warteschlange die nächste Aufgabe sofort aus oder wartet auf die Beendigung der aktuellen Aufgabe?

Eine serielle Warteschlange ist nicht „seriell“, nur weil ihre Aufgaben seriell abgegeben (in der Tat, die meisten Aufgaben in der Regel sind, auch auf parallele Warteschlangen), sondern weil die Aufgaben garantiert werden nacheinander durchgeführt werden, in dem Bestellung wurden sie eingereicht.

Thread.sleep funktioniert gut in einem Spielplatz, aber Ihr Spielplatz beendet seine Ausführung früh. Die Ausführung des Playgrounds endet, wenn der Kontrollfluss das Ende der Seite erreicht. Asynchrone Aufgaben wie diese werden nur dann beendet, wenn sie ausgeführt werden, bevor der Kontrollfluss das Ende der Seite erreicht, was sehr unwahrscheinlich ist.

Um den Spielplatz zu halten Ausführung auf unbestimmte Zeit (bis zum manuellen Abbruch), Verwendung:

import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 
+0

In der Tat. Danke für den Tipp auf PlaygroundSupport! – NeoWang

4

Eine serielle Warteschlange beginnt nicht um den nächsten Block ausgeführt wird, bis die vorherige beendet. Die Kontextumschaltung hat keinen Einfluss darauf. Wenn Sie sleep in einem Block anrufen, der an eine serielle Warteschlange gesendet wurde, wird die Warteschlange blockiert, bis der Ruhezustand beendet ist und Ihr Block die Ausführung fortsetzen kann. Ihr Ergebnis lautet also IN 1 -> OUT of 1 -> IN 2.

Beachten Sie, dass Sie in der Regel keine Blockierungen (wie sleep) in einem an eine Warteschlange gesendeten Block vornehmen möchten, da dies den gesamten Thread blockiert, sodass libdispatch nicht für andere Arbeiten verwendet werden kann. libdispatch wird neue Threads nach Bedarf erstellen, um weiterarbeiten zu können, aber es gibt eine Grenze dafür, wie viele neue Threads es spawnen wird.

Verwandte Themen