2012-04-08 2 views
1

저는 유닉스 환경에서 Richard Stevens의 Advance Programming을 읽고 있습니다.
스레드 동기화 범주 (장 - 11)에 코드가 있습니다. 이것은 동일한 유형의 많은 공유 구조에 대한 경쟁 조건을 피하는 방법을 보여주는 코드입니다.
이 코드리스트 fh위한 구조 (a 모든 푸 구조 추적리스트) & f_next 필드와 다른 synch.- 한 두 뮤텍스를 보이고 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 */ 
....... 

HASH(fp) 전처리가 무엇을하고
1) 의혹인가?
나는 그것이 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]은 해시 테이블이며 해시 함수로 매크로를 사용합니다.

1) HASH(fp)

fh에서 fp은 저장 위치를 ​​결정하기 위해 인덱스를 계산하고, 그것을 fp의 주소를 사용하여 인덱스를 계산하는 키로서 상기 어드레스를 사용한다. 주소를 긴 유형으로 쉽게 유형 변환 할 수 있습니다.

2 ) 별도의 체인라는 해시 충돌을 피하기 위해 링크 된 목록을 사용하여, 나는 다음과 같은 대구를 잘 생각하고,이 책에서 그것을 확인할 수 있습니다

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

가에 FP 요소를 삽입 헤더가 fh[idx]인데, fh[idx]의 초기 값은 null입니다.

관련 문제