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.