0

APUEを読んでいて、第11章のスレッド同期と混同しています。以下はコードスニペットです。

#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);
        fp->f_next = fh[idx];
        fh[idx] = fp;
        pthread_mutex_lock(&fp->f_lock);
        pthread_mutex_unlock(&hashlock);
        /* ... continue initialization ... */
        pthread_mutex_unlock(&fp->f_lock);
    }
    return(fp);
}

私の疑問は次のとおりです。

  1. なぜpthread_mutex_lock(&fp->f_lock)前に置くのpthread_mutex_unlock(&hashlock)ですか?代わりに後で配置できますか?

  2. fpローカル変数なので、一緒pthread_mutex_lock(&fp->f_lock)pthread_mutex_unlock(&fp->f_lock)削除できますか?

4

2 に答える 2

0

作成されたオブジェクトをループして、それらを使って何かをしている2番目のスレッドがあると思います。この場合:

  1. いいえ、ループスレッドが初期化される前に新しく作成されたオブジェクトにアクセスする可能性があるためです。

  2. いいえ、ループスレッドが半分初期化されている新しく作成されたオブジェクトにアクセスする可能性があるためです。

于 2012-12-22T07:19:57.393 に答える
0
  1. いいえ、pthread_mutex_lock(&hashlock)公開後のアクションは、新しく作成された構造をfhリストに追加することで他のスレッドに公開するためです。ハッシュロックが保持されている間、誰も変数にアクセスできません。ハッシュロックが解放されるとすぐに、ハッシュを介して他のスレッドにアクセスできるようになりますが、fp_>f_lockミューテックスをロックすると、だれもがを混乱させるのを防ぐことができfpます。

  2. 書かれたコードではありません。ハッシュを除いて構造全体が初期化された場合は、fp->f_lockミューテックスをロックせずに行うことができます。完了する直前に、ハッシュロックをロックし、新しく割り当てられたアイテムをハッシュテーブルにフックしてから、ハッシュロックを解放すれば、安全です。構造がハッシュテーブルに追加された後に排他的アクセスが必要な場合は、そのミューテックスを取得する必要があります。それが書かれている方法、それはミューテックスの待機していない取得です。変数にアクセスできる他のプロセスはありません。

    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);
        /* ... complete initialization except for adding to hash table ... */
        pthread_mutex_lock(&hashlock);
        fp->f_next = fh[idx];
        fh[idx] = fp;
        pthread_mutex_unlock(&hashlock);
    }
    

したがって、実行される内容の背後にはロジックがあります。合ってます。

于 2012-12-22T08:26:48.090 に答える