Joshua Rutschmann 7 年前
父节点
当前提交
560fd7c97e
共有 2 个文件被更改,包括 28 次插入14 次删除
  1. 22
    13
      hw8/simu1/ANSWERS.md
  2. 6
    1
      hw8/simu1/main-race.c

+ 22
- 13
hw8/simu1/ANSWERS.md 查看文件

@@ -32,28 +32,37 @@
32 32
 
33 33
 4. Helgrind gibt mir viele Informationen zur Lockreihenfolge. Es sagt, dass es durch das Festlegen des ersten Locks eine feste Reihenfolge gibt, in der neue Locks gesetzt werden müssen. Zusätzlich bekomme ich die Information, wo die Reihenfolge festgelegt wird und wo sie nicht eingehalten wird.
34 34
 
35
-5. Blah
35
+5. `main-deadlock-global.c`
36 36
 
37
-    1.
37
+    1. Das Problem der Lockreihenfolge sollte hier nicht auftreten, da im Worker ein globaler Lock gesetzt wird. Dieser blockiert während dem kritischen Bereich einfach alle anderen Threads.
38 38
 
39
-    2.
39
+    2. Beim Ausführen des Programms treten keine Fehler auf.
40 40
 
41
-    3.
41
+    3. helgrind sollte eigentlich keinen Fehler melden, da der globale Lock einen Deadlock verhindert.
42 42
 
43
-    4.
43
+    4. Da helgrind den Fehler dennoch erkennt, ist es ein sehr nützliches Werkzeug um Lockfehler zu erkennen.
44 44
 
45
-6.
45
+6. Dieser Code ist sehr ineffizient, da der Parent-Thread durch seine while-Schleife die CPU zu 100% auslastet und somit zum einen sehr viel Strom verbraucht und zum anderen die anderen Threads ihrer Rechenzeit "beraubt". Dies ist besonders auffällig, wenn das Child sehr lange benötigt.
46 46
 
47
-7. Blah
47
+7.
48 48
 
49
-    1.
49
+    1. helgrind meldet einen Data-Race-Fehler in der Variable `done`:
50
+        ```text
51
+        ==1064== Possible data race during read of size 4 at 0x602084 by thread #1
52
+        ==1064== Locks held: none
53
+        ==1064==    at 0x400CEB: main (main-signal.c:16)
54
+        ==1064==
55
+        ==1064== This conflicts with a previous write of size 4 by thread #2
56
+        ==1064== Locks held: none
57
+        ```
58
+        Dieser Fehler wird gemeldet, da der Kindthread in `done` eine 1 schreibt, sobald er fertig ist, im Elternthread jedoch eine while-Schleife mit dieser Variable läuft.
50 59
 
51
-    2.
60
+    2. Trotz der Meldung von helgrind ist der Code korrekt, da im Elternthread die Variable `done` nie geschrieben wird, sondern nur gelesen wird. "Verpasst" die while-Schleife die Änderung in `done`, so spielt das keine Rolle und die Schleife läuft einfach noch ein letztes Mal durch.
52 61
 
53
-8. Blah
62
+8. `main-signal-cv.c`
54 63
 
55
-    1.
64
+    1. Diese Version ist besser als die alte, da der Elternthread nicht mehr die CPU blockiert, während der Kindthread noch nicht fertig ist, sondern auf das Signal des Kinds wartet.
56 65
 
57
-    2.
66
+    2. Da der alte Code korrekt ist, spielt nur die Effizienz des Codes eine Rolle. Natürlich ist die hier angegebene Lösung außerdem deutlich eleganter.
58 67
 
59
-9.
68
+9. helgrind meldet keine Fehler bei der korrigierten Version. Dies liegt daran, dass nun ein Lock um die Variable `done` gesetzt wird, wenn diese geschrieben wird.

+ 6
- 1
hw8/simu1/main-race.c 查看文件

@@ -3,16 +3,21 @@
3 3
 #include "mythreads.h"
4 4
 
5 5
 int balance = 0;
6
+pthread_mutex_t mut;
6 7
 
7 8
 void* worker(void* arg) {
8
-    //balance++; // unprotected access
9
+    pthread_mutex_lock(&mut);
10
+    balance++; // protected access
11
+    pthread_mutex_unlock(&mut);
9 12
     return NULL;
10 13
 }
11 14
 
12 15
 int main(int argc, char *argv[]) {
13 16
     pthread_t p;
14 17
     Pthread_create(&p, NULL, worker, NULL);
18
+    pthread_mutex_lock(&mut);
15 19
     balance++; // unprotected access
20
+    pthread_mutex_unlock(&mut);
16 21
     Pthread_join(p, NULL);
17 22
     return 0;
18 23
 }

正在加载...
取消
保存