HW6:Threads and Locking

MIT6.828_HW6_Threads and Locking

ph.c程序

这个实验给了我们一个实例ph.c,这个程序会创建一个线程,thread,如下所示:

static void *
thread(void *xa)
{
  long n = (long) xa;
  int i;
  int b = NKEYS/nthread;
  int k = 0;
  double t1, t0;
  //  printf("b = %d\n", b);
  t0 = now();
  for (i = 0; i < b; i++) {
    // printf("%d: put %d\n", n, b*n+i);
    put(keys[b*n + i], n);
  }
  t1 = now();
  printf("%ld: put time = %f\n", n, t1-t0);
  // Should use pthread_barrier, but MacOS doesn't support it ...
  __sync_fetch_and_add(&done, 1);
  while (done < nthread) ;
  t0 = now();
  for (i = 0; i < NKEYS; i++) {
    struct entry *e = get(keys[i]);
    if (e == 0) k++;
  }
  t1 = now();
  printf("%ld: get time = %f\n", n, t1-t0);
  printf("%ld: %d keys missing\n", n, k);
  return NULL;
}

这个线程先是通过put操作,将数据放入到table中,table是一个数组,大小为NBUCKET,每个元素为一个链表。put操作的时候每个线程会insert同样数量的数据,例如有2个线程,那么线程0会将keys[0]到keys[49999]的值inserttable中,线程·会将keys[50000]到keys[99999]inserttable中。通过while(down < nthread)语句,保证所有线程先进行了put操作之后,才会进行get操作。而get操作,则是遍历keys[100000]数组,找到每个keys[i]对应的value,如果找不到,那么计数k++

missing keys的原因

因为在多线程的时候,由于insert并不是原子操作,导致两个线程冲突,有部分数据并没有inserttable中。因此可以对insert操作加锁。

static
void put(int key, int value)
{
  int i = key % NBUCKET;
  pthread_mutex_lock(&lock);  // acquire lock
  insert(key, value, &table[i], table[i]);
  pthread_mutex_unlock(&lock);  // release lock
}

加锁之后,put的时间会变长

  • 未加锁时
    在这里插入图片描述
  • 加锁之后
    在这里插入图片描述

注意

下面这种加锁方式会存在问题,原因在于put函数中,其&table[i]table[i]的地址会因为其他线程插入数据导致这两部分的地址失效。

static void
insert(int key, int value, struct entry **p, struct entry *n)
{
  pthread_mutex_lock(&lock);  // acquire lock
  struct entry *e = malloc(sizeof(struct entry));
  e->key = key;
  e->value = value;
  e->next = n;
  *p = e;
  pthread_mutex_unlock(&lock);  // release lock
}
static
void put(int key, int value)
{
  int i = key % NBUCKET;
  insert(key, value, &table[i], table[i]);
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值