Ein Kollege hat kürzlich vorgeschlagen, dass ich Pthreads anstelle von GCD verwende, weil es "viel schneller" ist. Ich stimme nicht zu, dass es schneller ist, aber was ist das Risiko mit Pthreads?
Mein Gefühl ist, dass sie letztendlich nirgends so idiotisch wie GCD sein werden (und mein Team von einem ist 50% Idioten). Sind Pthreads schwer zu bekommen?
GCD und Pthreads sind beides asynchrone Arbeitsweisen, die sich jedoch deutlich unterscheiden. Die meisten Beschreibungen von GCD beschreiben es in Bezug auf Threads und Thread-Pooling, aber wie DrPizza es ausdrückt
konzentriert sich auf [Threads und Threadpools], um den Punkt zu verfehlen. Der Wert von GCD liegt nicht im Thread-Pooling, sondern in queuing .
Grand Central Dispatch für Win32: warum ich will es
GCD hat einige Vorteile gegenüber APIs wie Pthreads.
GCD unterstützt mehr und mehr "Inseln der Serialisierung in einem Meer von Parallelismen". GCD macht es einfach, viele Sperren und Mutexe zu vermeiden und Variablen zu konditionieren, die die normale Art der Kommunikation zwischen Threads sind. Das liegt daran, dass Sie Ihr Programm in Aufgaben zerlegen und GCD dafür sorgt, dass die Aufgabeneingabe und -ausgabe in den entsprechenden Thread hinter den Kulissen erfolgt. Die Programmierung mit GCD erlaubt es Ihnen, ziemlich viel seriell zu schreiben und sich nicht zu viele Gedanken über die Dinge zu machen, um die sich die Leute im Thread-Code sorgen. Das macht den Code einfacher und weniger fehleranfällig.
GCD kann für Sie skalieren, so dass das Programm so viel Parallelität verwendet wie die Abhängigkeiten zwischen den Tasks, in die Sie Ihr Programm zerlegt haben, und der Hardware, die es erlaubt. Natürlich ist das Entwickeln des Programms, das skalierbar sein soll, im Allgemeinen das harte Bit, aber Sie werden immer noch etwas brauchen, um diese Arbeit zu nutzen, um so viel wie möglich parallel zu laufen. Work Stealing Scheduler wie GCD machen diesen Teil.
GCD ist zusammensetzbar. Wenn Sie explizit Threads für Dinge erstellen, die Sie asynchron oder parallel ausführen möchten, kann es zu einem Problem kommen, wenn Bibliotheken, die Sie verwenden, dasselbe tun. Angenommen, Sie entscheiden, dass Sie acht Threads gleichzeitig ausführen können, da so viele Threads für Ihr Programm effektiv sind, wenn der Computer ausgeführt wird. Und dann sagen Sie, dass eine Bibliothek, die Sie für jeden Thread verwenden, dasselbe tut. Jetzt können Sie bis zu 64 Threads gleichzeitig ausführen, was mehr ist, als Sie für Ihr Programm wissen.
Thread-Pooling löst dies, aber jeder muss denselben Thread-Pool verwenden. GCD verwendet Thread-Pooling intern und bietet den gleichen Pool für alle.
GCD stellt eine Reihe von "Quellen" zur Verfügung und macht es einfach, ein ereignisgesteuertes Programm zu schreiben, das von den Quellen abhängig ist oder von ihnen Eingaben erhält. Beispielsweise können Sie sehr einfach eine Warteschlange einrichten, um eine Aufgabe jedes Mal zu starten, wenn Daten in einem Netzwerk-Socket verfügbar sind oder wenn ein Timer ausgelöst wird oder was auch immer.
Ich denke nicht, dass sie schwer zu korrigieren sind, aber nachdem ich im Laufe der Jahre mit vielen verschiedenen Ansätzen gearbeitet habe (Pthreads, GCD, NSThread, NSOperationQueue usw.) habe ich keine Beweise dafür Unterstütze eine Behauptung wie "Pthreads sind viel schneller." Selbst wenn sie schneller wären (und ich würde erwarten, dass der Unterschied bestenfalls marginal ist), sage ich immer: "Benutze die Abstraktion auf höchstem Niveau, die den Job erledigt." Vermeiden Sie auch eine vorzeitige Optimierung.
Anekdotisch ist GCD verdammt schnell . Wie ich es sehe, ist Portabilität der Hauptvorteil von Pthreads gegenüber GCD. Wenn dies der exklusive OSX / iOS-Code ist, würde ich keinerlei Vorteile für die Verwendung von Pthreads sehen, wenn keine empirischen Beweise für das Gegenteil vorliegen.
Ignoriere die anderen gut durchdachten technischen Gründe, weil sie nicht relevant sind . Sie schreiben keine Software für einen Benchmark, oder? Irgendwann wird ein Benutzer vor Ihrem Gerät sitzen und versuchen, es zu benutzen. Und weißt du, was passiert, wenn du Pthreads anstelle von GCD verwendest? Was passiert ist, dass Ihre Software nicht skaliert gut in Gegenwart anderer Software Multitasking zur gleichen Zeit , weil es Kampf für die CPU unter der Annahme, es ist die einzige Software zur gleichen Zeit läuft . Was ist verrückt. Niemand betreibt Single-Task-Betriebssysteme mehr. Selbst bei single task iOS werden viele Dinge im Hintergrund ausgeführt.
Wenn stattdessen alle Programme, die Sie ausgeführt haben, GCD verwendet haben, kann das Betriebssystem die Anzahl der gleichzeitig ausgeführten Tasks auf ihren Warteschlangen skalieren und somit die Anzahl der tatsächlichen Prozessoren besser abstimmen, was den Task-Switching-Overhead reduziert.
Wenn Ihr Programm keine Pseudo-Realtime-Low-Latenz benötigt und somit ein dedizierter Thread, um Dinge zu verarbeiten, sobald es verfügbar ist (vielleicht die Definition des Kollegen " viel schneller "), Chancen GCD wird für den Benutzer überlegen sein, da es die auf seinem Gerät verfügbaren Ressourcen besser nutzt. Selbst wenn die API von GCD schrecklich oder langsam wäre, würde es sich lohnen, sie gegenüber anderen Lösungen einzusetzen, die nicht über verschiedene Prozesse hinweg skalieren.
Wahrscheinlich wird NSThread mit der pthreads-Bibliothek implementiert, der Punkt ist, dass je niedriger die Ebene eines Konzepts ist, desto mehr müssen Sie unnütze und sich wiederholende Aufgaben erledigen.
Also ist die Pthreads-Bibliothek nicht so schwer zu lernen, mein Professor an der Universität hat es gelehrt, und sogar die meisten (sie so nennen) lernten langsam, die Leute konnten die Bibliothek benutzen, vielleicht nach dem Zufallsprinzip Kopieren-Einfügen des Codes nur für träge, aber den Job erfolgreich zu erledigen.
Ich schlage also vor, dass Sie eine pthread-Wrapper-Klasse implementieren, es ist einfach zu machen.
Auf diese Weise eliminierst du das unnütze Zeug, zum Beispiel machst du das tausendmal:
%Vor%Also (wenn das Ihr Fall ist, aber es ist nur ein Beispiel), können Sie immer NULL übergeben, und dasselbe gilt für andere Funktionen.
Sobald die Klasse implementiert ist, wird nicht gesagt, dass sie schneller ist als GCD.
GCD führt einige Optimierungen durch, zum Beispiel können zwei Blöcke im selben Thread ausgeführt werden.
Ich schlage daher vor, Ihre definierte Klasse nur zu verwenden, wenn sie schneller als GCD ist, um sie mit dem Zeitprofiler zu testen.
Tags und Links objective-c grand-central-dispatch pthreads nsthread