这个演员阵容和任务是关于什么的?

时间:2012-04-08 14:07:56

标签: pthreads preprocessor mutex

我正在阅读Richard Stevens在unix环境中的高级编程 线程同步类别中有一个代码(第11章)。 这是显示如何避免相同类型的许多共享结构的竞争条件的代码 此代码显示两个用于同步的互斥锁 - 一个用于列表fh(一个跟踪所有foo结构的列表)&结构f_next的{​​{1}}字段和另一个字段 代码是:

foo

怀疑是
1) #include <stdlib.h> #include <pthread.h> #include <stdio.h> #include <unistd.h> #define NHASH 29 #define HASH(fp) (((unsigned long)fp)%NHASH) struct foo *fh[NHASH]; pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER; struct foo { int f_count; pthread_mutex_t f_lock; struct foo *f_next; /* protected by hashlock */ int f_id; /* ... more stuff here ... */ }; struct foo * foo_alloc(void) /* allocate the object */ { struct foo *fp; int idx; if ((fp = malloc(sizeof(struct foo))) != NULL) { fp->f_count = 1; if (pthread_mutex_init(&fp->f_lock, NULL) != 0) { free(fp); return(NULL); } idx = HASH(fp); pthread_mutex_lock(&hashlock); ///////////////////// HERE ----------------- fp->f_next = fh[idx]; fh[idx] = fp->f_next; //////////////////// UPTO HERE ------------- pthread_mutex_lock(&fp->f_lock); pthread_mutex_unlock(&hashlock); /* ... continue initialization ... */ pthread_mutex_unlock(&fp->f_lock); } return(fp); } void foo_hold(struct foo *fp) /* add a reference to the object */ ....... 预处理器在做什么?
我知道它是对HASH(fp)存储然后取其模数进行类型转换。但是,在函数fp中,我们只是传递新分配的foo结构的地址 为什么我们这样做我知道这会给我一个0到28之间的整数 - 存储在数组foo_alloc中。但为什么我们采用模数地址。为什么有这么多随机化?

2)假设我接受了这一点,现在这两条线正在做什么(在代码中也突出显示):

fh

我希望最初fp->f_next = fh[idx]; fh[idx] = fp->f_next; 有任何垃圾值,我分配给foo的fh[idx]字段,并在下一行中发生了什么,同样的任务,但顺序相反。

1 个答案:

答案 0 :(得分:0)

struct foo *fh[NHASH]是一个哈希表,并使用HASH宏作为哈希函数。

1)HASH(fp)计算索引,以决定fh存储fp的位置,并使用fp的地址并将地址用作关键字计算指数。我们可以轻松地将地址类型转换为long类型。

2)使用链表来避免称为单独链接的哈希冲突,我认为以下鳕鱼是正确的,您可以在书中查看:

fp->f_next = fh[idx];
fh[idx] = fp;

将fp元素插入到链接列表fh[idx]的标头中,fh[idx]的初始值为空。