Skip to content

Using threads (moderate)

预处理

  1. 构建 ph 程序

文件notxv6/ph.c包含一个简单的哈希表

如果单个线程使用,该哈希表是正确的,但是多个线程使用时,该哈希表是不正确的

bash
eason@eason-VMware-Virtual-Platform:~/work/xv6-labs-2020$ make ph
gcc -o ph -g -O2 notxv6/ph.c -pthread
  1. 运行 ./ph 1

使用单线程运行该哈希表

bash
eason@eason-VMware-Virtual-Platform:~/work/xv6-labs-2020$ ./ph 1
100000 puts, 6.372 seconds, 15695 puts/second
0: 0 keys missing
100000 gets, 6.236 seconds, 16035 gets/second
  1. 运行 ./ph 2

使用两个线程运行该哈希表

bash
eason@eason-VMware-Virtual-Platform:~/work/xv6-labs-2020$ ./ph 2
100000 puts, 2.759 seconds, 36248 puts/second
1: 14873 keys missing
0: 14873 keys missing
200000 gets, 6.531 seconds, 30622 gets/second

这是一个优秀的“并行加速”,大约达到了人们希望的2倍

但keys missing的两行表示散列表中本应存在的大量键不存在,出现了一些问题

定义互斥锁数组

diff --git a/notxv6/ph.c b/notxv6/ph.c
index 6df1500..60f2703 100644
--- a/notxv6/ph.c
+++ b/notxv6/ph.c
@@ -16,6 +16,7 @@ struct entry {
 struct entry *table[NBUCKET];
 int keys[NKEYS];
 int nthread = 1;
pthread_mutex_t lock[NBUCKET] = { PTHREAD_MUTEX_INITIALIZER }; // 每个散列桶一把锁
 
 double
 now()

在 put() 中加锁

diff --git a/notxv6/ph.c b/notxv6/ph.c
index 6df1500..60f2703 100644
--- a/notxv6/ph.c
+++ b/notxv6/ph.c
@@ -50,8 +51,10 @@ void put(int key, int value)
     // update the existing key.
     e->value = value;
   } else {
    pthread_mutex_lock(&lock[i]);
     // the new is new.
     insert(key, value, &table[i], table[i]);
    pthread_mutex_unlock(&lock[i]);
   }
 }

测试

gcc重新编译运行

bash
eason@eason-VMware-Virtual-Platform:~/work/xv6-labs-2020$ make ph
gcc -o ph -g -O2 notxv6/ph.c -pthread
eason@eason-VMware-Virtual-Platform:~/work/xv6-labs-2020$ ./ph 2
100000 puts, 2.721 seconds, 36749 puts/second
0: 0 keys missing
1: 0 keys missing
200000 gets, 5.111 seconds, 39134 gets/second