1

UNIX環境でRichard StevensのAdvance Programmingを読んでいます。
スレッド同期カテゴリ (第 11 章) にコードがあります。これは、同じタイプの多くの共有構造の競合状態を回避する方法を示すコードです。
このコードは、同期用の 2 つのミューテックスを示しています。1 つはリストfh(すべての foo 構造を追跡するリスト) &f_nextフィールド用、もう 1 つは構造用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)私がそれを受け入れると仮定すると、この後、これらの2行が何をしているのか(コードでも強調表示されています):

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

fh[idx]最初に fooのフィールドに割り当てたガベージ値がありf_next、次の行で何が起こっているかを願っています。これも同じ割り当てですが、順序が逆です。

4

1 に答える 1