2012-04-08 30 views
1

我正在阅读理查德史蒂文斯在unix环境下的高级编程。
线程同步类(第11章)中有一个代码。 这是代码显示正在显示如何避免相同类型的许多共享结构的竞态条件。
此代码示出了两个互斥为synch.-一个用于列表fh的结构(其保持所有FOO结构的轨道列表)& f_next字段,另一个foo
的代码是:什么是演员和任务是关于什么?

#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 */ 
....... 

的疑问是
1)什么是HASH(fp)预处理器在做什么?
我知道它是类型化的fp存储,然后以它为模。但是,在函数foo_alloc中,我们只是传递新分配的foo结构的地址。
为什么我们这样做我知道这会给我一个0到28之间的整数 - 存储在数组fh。但是,我们为什么要模拟一个地址。为什么有这么多的随机化?

2)假如我接受的是,现在经过这什么这两条线都在做(也强调了代码):

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

我希望最初fh[idx]有我分配给任何垃圾值f_next foo字段,并在下一行发生了什么,再次是相同的作业,但顺序相反。

回答

0
struct foo *fh[NHASH]

是一个哈希表,并使用HASH宏作为哈希函数。

1)HASH(fp)计算来决定,其中在fh存储fp索引,并且它使用fp的地址,并使用地址作为密钥来计算索引。我们可以很容易地将地址转换为长类型。

2)使用链表,避免哈希冲突称为分离链,我认为以下鳕鱼是正确的,你可以在这本书检查:

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

插入FP元到链表fh[idx],并且fh[idx]的初始值的报头为空。