1. 程式人生 > >MIT6.828 HW6: Threads and Locking

MIT6.828 HW6: Threads and Locking

  這次作業我們將探索使用執行緒和鎖來並行程式設計Hash表。下載pc.c程式然後編譯執行。
  其實pc.c程式主要工作是使用隨機數生成keys,然後利用線性hash將其插入5個雜湊槽中,最後再取出每個key。
  當使用2個執行緒來執行時,將會把keys分成2組,讓2個執行緒分別put key,最後2個執行緒都做get key。輸出用例:

0: put time = 2.871728
1: put time = 2.957073
1: lookup time = 12.731078
1: 1 keys missing
0: lookup time = 12.731874
0: 1 keys
missing completion time = 15.689165

  當使用1個執行緒來執行時,輸出用例:

0: put time = 5.350298
0: lookup time = 11.690395
0: 0 keys missing
completion time = 17.040894

  2個重要點:
  (1).2個執行緒的完成時間與1個執行緒的完成時間差不多,但是2個執行緒做了2次get key操作,有效地實現了並行。
  (2).2個執行緒在get keys,會發生多個key missing情況。
  主要問題是:
  put key時呼叫insert函式時,會將新的entry插入到連結串列的頭部,即修改連結串列頭部指標,導致錯誤。

static void
insert(int key, int value, struct entry **p, struct entry *n)
{
        struct entry *e = malloc(sizeof(struct entry));
        e->key = key;
        e->value = value;
        e->next = n;
        *p = e;
}

  當只用1個互斥鎖時,加鎖解鎖操作可以在put函式前後。若根據槽的個數使用相應個數的自旋鎖,加鎖解鎖操作可以在insert函式前後,能有效地提高執行效率。
  由於get操作並未涉及到修改hash表,即只有讀取操作,所以可以不用進行鎖保護。