linux - Bagaimana untuk memahami kunci mutex dan pembolehubah keadaan?
仅有的幸福
仅有的幸福 2017-06-12 09:24:46
0
1
1220

Kod berikut adalah daripada "Tutorial Amalan Pengaturcaraan Unix/Linux". Fungsinya ialah menggunakan dua utas untuk mengira bilangan perkataan dalam dua fail masing-masing, dan mengira jumlah bilangan dalam utas utama. Di bawah ialah tangkapan skrin operasi:

Tetapi selepas membacanya untuk masa yang lama, masih sukar untuk memahami pembolehubah penguncian, buka kunci dan keadaan dalam kod berikut.
Saya nak tanya:

  1. Apabila memanggil pthread_cond_wait时会释放互斥锁,然后挂起主线程,并等待条件变量的发生变化,当其他线程调用pthread_cond_signal时,如果互斥锁是被锁住的,那么主线程中的pthread_cond_wait dalam utas utama, adakah ia akan menunggu mutex dibuka, kemudian mengunci mutex sebelum kembali?

  2. Jika seperti yang diterangkan dalam 1, pthread_cond_wait收到了pthread_cond_signal发来的信号,但是未锁定互斥锁之前,又被其他线程抢了先,锁住了互斥锁,那不是pthread_cond_waitmasih perlu menunggu kunci mutex dibuka?

  3. Sekiranya boleh, saya harap ia dapat membantu menjelaskan proses perlaksanaan program ini.

Terima kasih banyak-banyak.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <ctype.h>

struct arg_set {            /* two values int one arg */
    char    *filename;      /* file to examine */
    int     count;          /* number of words */
    int     code;
};

struct arg_set  *mailbox = NULL;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  flag = PTHREAD_COND_INITIALIZER;

void *count_words(void *);

int main(int argc, char *argv[])
{
    pthread_t t1, t2;               /* two threads */
    struct arg_set args1, args2;    /* two argsets */
    int reports_int = 0;
    int total_words = 0;

    if (argc != 3) {
        fprintf(stderr, "usage: %s file1 file2", argv[0]);
        exit(1);
    }

    pthread_mutex_lock(&lock);

    args1.filename  = argv[1];
    args1.count     = 0;
    args1.code      = 1;
    pthread_create(&t1, NULL, count_words, (void *)&args1);

    args2.filename  = argv[2];
    args2.count     = 0;
    args2.code      = 2;
    pthread_create(&t2, NULL, count_words, (void *)&args2);

    while (reports_int < 2) { // 等待其他线程结束
        printf("MAIN: waiting for flag to go up\n");
        pthread_cond_wait(&flag, &lock);
        printf("MAIN: Wow! flag was raised, I have the lock\n");
        printf("%7d: %s\n", mailbox->count, mailbox->filename);
        total_words += mailbox->count;
        if (mailbox == &args1)
            pthread_join(t1, NULL);
        if (mailbox == &args2)
            pthread_join(t2, NULL);
        mailbox = NULL;
        pthread_cond_signal(&flag);
        reports_int++;
    }

    printf("%7d: total words\n", total_words);

    return 0;
}

void *count_words(void *a)
{
    struct arg_set *args = a;
    FILE *fp;
    int c, prevc = 'rrreee';

    if ((fp = fopen(args->filename, "r")) != NULL) { // 统计单词个数
        while ((c = getc(fp)) != EOF) {
            if (!isalnum(c) && isalnum(prevc))
                args->count++;
            prevc = c;
        }
        fclose(fp);
    } else
        perror(args->filename);

    printf("COUNT %d: waiting to get lock\n", args->code);
    pthread_mutex_lock(&lock);
    printf("COUNT %d: have lock, storing data\n", args->code);
    if (mailbox != NULL)
        pthread_cond_wait(&flag, &lock);
    mailbox = args;
    printf("COUNT %d: raising flag\n", args->code);
    pthread_cond_signal(&flag);
    printf("COUNT %d: unlocking box\n", args->code);
    pthread_mutex_unlock(&lock);

    return NULL;
}
仅有的幸福
仅有的幸福

membalas semua(1)
扔个三星炸死你

Tiada apa-apa yang rumit Selepas benang utama memperoleh kunci, ia akan tidur dan menunggu isyarat untuk membangunkannya.

pthread_cond_signalIni isyaratnya

Kunci jenis ini sedikit berbeza daripada kunci lain Jenis kunci lain ialah: benang terpakai untuk kunci, dan jika tidak mendapat kunci, benang akan tidur dan menunggu.

Kunci jenis ini tidur apabila ia dikunci, menunggu benang lain untuk membangunkannya.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan