2012-04-08 6 views
1

Ich lese Richard Advance Advance Programmierung in Unix-Umgebung.
Es gibt einen Code in der Thread-Synchronisationskategorie (Kapitel - 11). Dies ist Code, der zeigt, wie Race Conditions für viele gemeinsame Strukturen desselben Typs vermieden werden können.
Dieser Code zeigt zwei Mutex für synch.- eine für eine Liste fh (eine Liste, die den Überblick über alle foo Strukturen halten) foo für die Struktur & f_next Feld und eine andere
Der Code ist:Worum geht es in dieser Besetzung und Aufgabe?

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

Der Zweifel ist
1) Was ist HASH(fp) Vorprozessor tun?
Ich weiß, dass es Typcasting ist, was ist fp speichern und dann seine modulo. Aber in der Funktion foo_alloc übergeben wir nur die Adresse der neu zugewiesenen Foo-Struktur.
Warum tun wir das, weiß ich, dass dies mir eine ganze Zahl zwischen 0 und 28 geben wird - in Array fh zu speichern. Aber warum nehmen wir modulo einer Adresse. Warum gibt es so viel Randomisierung?

2) nehme ich akzeptieren, dass, jetzt danach, was diese beiden Linien tun (auch im Code hervorgehoben):

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

Ich hoffe zunächst fh[idx] hat keinen Müll Wert, den ich die zugewiesenen f_next Feld von foo und in der nächsten Zeile, was passiert, wieder die gleiche Aufgabe, aber in umgekehrter Reihenfolge.

Antwort

0

ist eine Hash-Tabelle, und verwenden Sie das HASH Makro als Hash-Funktion.

1) HASH(fp) berechnet den Index, um zu entscheiden, wo die in den fhfp zu speichern, und es verwendet die Adresse der fp und verwendet die Adresse als Schlüssel, den Index zu berechnen. Wir können die Adresse einfach auf den langen Typ tippen.

2) die verknüpfte Liste Verwenden Sie die Hash-Kollisionen genannt getrennte Verkettung, und ich denke, die folgende Kabeljau ist richtig, und Sie können es in dem Buch zu vermeiden:

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

das fp Element an dem Einsatz Header der verknüpften Liste fh[idx], und der Anfangswert der fh[idx] ist Null.

Verwandte Themen