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
    评论
/usr/bin/ld: cannot find -lThreads::Threads collect2: error: ld returned 1 exit status 这个错误是由于链接器无法找到名为libThreads::Threads的库文件导致的。这个错误通常发生在编译和链接过程中,当链接器尝试将目标文件与所需的库文件进行链接时。 解决这个问题的方法是确保系统中已经安装了所需的库文件,并且库文件的路径正确配置。你可以按照以下步骤来解决这个问题: 1. 确认库文件是否已经安装:使用以下命令检查系统中是否已经安装了libThreads::Threads库文件: ```shell ls /usr/lib/libThreads::Threads.so ``` 2. 如果库文件未安装,你需要安装它。你可以使用包管理器来安装库文件,具体命令取决于你使用的操作系统和包管理器。例如,在Ubuntu上,你可以使用以下命令安装libThreads::Threads库文件: ```shell sudo apt-get install libThreads::Threads-dev ``` 3. 如果库文件已经安装,但链接器仍然无法找到它,可能是因为库文件的路径没有正确配置。你可以尝试将库文件的路径添加到链接器的搜索路径中。具体的方法取决于你使用的编译器和构建系统。以下是一些常见的方法: - 使用编译器选项指定库文件的路径。例如,在gcc中,你可以使用以下命令来指定库文件的路径: ```shell gcc -L/path/to/lib -lThreads::Threads source.c -o executable ``` - 在构建系统的配置文件中添加库文件的路径。例如,在Makefile中,你可以使用以下语法来指定库文件的路径: ```makefile LDFLAGS += -L/path/to/lib LDLIBS += -lThreads::Threads ``` - 将库文件的路径添加到LD_LIBRARY_PATH环境变量中。例如,在bash中,你可以使用以下命令来添加库文件的路径: ```shell export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH ``` 通过以上步骤,你应该能够解决/usr/bin/ld: cannot find -lThreads::Threads collect2: error: ld returned 1 exit status错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值