ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/docs/pws2009/threads.pod
Revision: 1.1
Committed: Sat Jan 17 03:12:52 2009 UTC (17 years, 9 months ago) by root
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =encoding utf-8
2    
3     =head1 Threads in dynamischen Sprachen und warum Perl-Pseudo-Threads sterben sollten
4    
5     Wie man am Titel sieht, soll es im folgenden um zwei verwandte Themen
6     gehen. Einerseits möchte ich grundsätzliche Gedanken über Threads
7     liefern, einige Vorurteile ausräumen und erläutern, wie Threads in
8     dynamischen Sprachen implementiert werden und warum dies so ist.
9    
10     Andererseits möchte ich erläutern, warum Perl keine Threads unterstützt
11     und weshalb Perls sogenannte Threads eher sterben sollten, da sie
12     mehr Schaden anrichten als sie helfen. Letzteres muss nicht einmal zu
13     Inkompatibilitäten führen: da Perl-Threads keine sind, lassen sie sich
14     effizient ohne emulieren.
15    
16     =head2 Was ist ein Thread - Eine Begriffsbestimmung
17    
18     Am einfachsten erklärt man Threads, in dem man sie Prozessen
19     gegenüberstellt:
20    
21     Prozesse haben (üblicherweise) einen eigenen Adressraum, d.h. Variablen
22     existieren als Kopie in jedem Prozess und sind unabhängig
23     voneinander. Außerdem besitzt ein Prozess eine "Continuation", d.h. im
24     wesentlichen den aktuellen "Ort" der Programmausführung. Unter Unix
25     kommen dann noch andere Ressourcen wie File-Descriptoren hinzu, aber im
26     wesentlichen ist es das.
27    
28     Ein Thread nun ist im wesentlichen ein abgespeckter Prozess (daher werden
29     sie auch oft "LWPs" - Light Weight Processes genannt), bei dem eine oder
30     mehrere dieser Ressourcen gemeinsam genutzt werden, insbesondere der
31     Adressraum. Daher kann man Threads auch als Untereinheit von Prozessen
32     ansehen: ein Prozess kann aus ein oder mehreren Threads bestehen, die sich
33     alle den gleichen Adressraum (die gleichen Variableninhalte) teilen.
34    
35     Bei Threads gibt eine Menge verschiedene Variationen. Die wichtigsten sind:
36    
37     =over 4
38    
39     =item Kooperative Threads
40    
41     Die "Urform" der Threads - diese Threads werden "kooperativ" genannt,
42     nicht, weil sie es sind, sondern, weil sie es sein müssen: Sobald
43     ein Thread ausgeführt wird, läuft dieser ohne Unterbrechung, bis er
44     freiwillig die CPU an einen anderen Thread abgibt. Tut ein Thread dies
45     nicht, läuft nichts anderes im System.
46    
47     Manchmal werden Kooperative Threads auch Koroutinen, Fibers oder
48     Continuations genannt, was genau genommen falsch ist, aber im wesentlichen
49     bezeichnen diese Begriffe dasselbe.
50    
51     Windows 3.11, das Oberon-System oder das Coro-Modul von Perl sind
52     Beispiele für kooperatives Threading.
53    
54     =item Preemptive Threads
55    
56     Um das Problem der Monopolisierung des Rechners durch einen unkooperativen
57     (weil z.B. ferhlerhaften) Thread zu umgehen, wurden "preemptive" Threads
58     erfunden: Diese werden ohne ihr Zutun regelmäßig "unterbrochen" (z.B.
59     durch einen Timer) und dadurch von der CPU "verdrängt" (preempted).
60    
61     Diese Art von Threads wird oft auch "time-slicing" (Zeitscheibenverfahren)
62     genannt, da hierbei ein Thread üblicherweise eine bestimmte Zahl von
63     Zeiteinheiten erhält und, wenn er in dieser Zeit die CPU nicht freigibt,
64     wird er automatisch verdrängt.
65    
66     Neuere Windows-Versionen, alle Unix-Versionen und insbesondere alle
67     Thread-Systeme dynamischer Sprachen (d.h. Ruby, Python usf.) benutzen
68     dieses Verfahren.
69    
70     =item "Kernel-Threads" und "Userspace-Threads"
71    
72     Ein weiterer wichtiger Unterschied zwischen Thread-Systemen ist, ob sie
73     vom Betriebssystem selbst implementiert werden oder innerhalb eines
74     Prozesses.
75    
76     In letzterem Fall teilen sich alle Threads dieselbe Prozess-Continuation,
77     was nichts anderes bedeutet, als daß diese Threads niemals parallel
78     laufen können (z.B. auf einem SMP-System).
79    
80     Der Begriff "Kernel-Thread" bezeichnet im Gegensatz dazu die Variante, bei
81     er die Threads tatsächlich parallel/gleichzeitig arbeiten können, obwohl
82     dies nicht zwangsweise im "Kernel" implementiert werden muss.
83    
84     Userspace-Threads sind im allgemeinen um ein vielfaches schneller als
85     Kernel-Threads - die Userspace-Threading-Bibliothek, die von Coro benutzt
86     wird schaltet mehr als 100 mal schneller zwischen Threads um als der
87     Linux-Kernel. Selbst auf Perl-Ebene schalten die Userspace-Threads von
88     Coro mehr als 14 mal schneller als die Linux-Kernel-Threads.
89    
90     =back
91    
92     =head2 Wozu wurden Threads erfunden, wozu eignen sie sich?
93    
94     =head3 Single-Cores
95    
96     Multi-Core und Multiprozessorsysteme sind erst seit kurzer Zeit
97     verbreitet. Die überwiegende Mehrheit der Rechner besitzt nach wie vor
98     nur einzelne CPUs.
99    
100     Moderne CPUs besitzen im allgemeinen spezielle Hardware, um Prozesse zu
101     unterstützen, z.B. eine Memory-Management-Unit (MMU) um den Adressraum
102     zu verwalten und einen Translation-Lookaside-Buffer (TLB) um das ganze zu
103     beschleunigen.
104    
105     Da jeder Prozess seinen eigenen Adressraum besitzt, muss die MMU bei jedem
106     Umschalten neu konfiguriert werden, Caches wie der TLB gehen häufig
107     verloren. Dies kann die Performance empfindlich beeinflussen, da die meisten
108     CPUs nur einen Zustand im Cache behalten können.
109    
110     Die natürliche Lösung gegen zu viele Rekonfigurationen sind weniger
111     Rekonfigurationen bei Prozesswechseln. Wechselt man den Adressraum nicht,
112     so erhält man Threads auf natürliche Weise, da die CPU einfach den alten
113     Adressraum weiter benutzt.
114    
115     Daher stammt der Name "Light Weight Processes" (leichtgewichtige
116     Prozesse): Threads werden hier als Prozesse mit weniger "Zustand" behandelt.
117    
118     Dies beschleunigt das Prozessumschalten erheblich, vor allem auf älteren
119     Systemen.
120    
121     =head3 Multiprozessor- oder Multi-Core-Systeme
122    
123     Ein weit verbreiteter Irrtum ist es, daß Threads sich gut für die
124     Parallelisierung eignen, d.h. echte Parallelverarbeitung auf einem
125     Multiprozessorsystem.
126    
127     Dies ist allerdings nicht der Fall: Das Problem, daß es nur eine Instanz
128     der Caches oder MMU gibt, existiert bei mehreren CPU-Kernen nicht, da
129     diese alle ihren eigenen Cache besitzen.
130    
131     Im Gegenteil: Dadurch, daß Threads viele Ressourcen gemeinsam nutzen,
132     muss das Betriebssystem durch aufwändige (und langsame) Verwaltung
133     sicherstellen, daß auch alle CPUs im System den gleichen Zustand haben.
134    
135     Wenn z.B. ein Prozess mit mehreren Threads auf einem Multi-Core-System
136     arbeitet und der eine Thread vom Betriebssystem Speicher anfordert, so
137     muß das Betriebssystem synchron alle anderen CPUs anhalten, ihnen den
138     neuen Zustand mitteilen, warten, bis alle den Zustand übernommen haben
139     und kann erst dann weiterarbeiten.
140    
141     F<http://data.plan9.de/matmult>
142    
143     =begin latex
144    
145     \begin{center}
146     \includegraphics{mat2.eps}
147     \end{center}
148    
149     =end latex
150