linux - Wie versteht man Mutex-Sperren und Bedingungsvariablen?
仅有的幸福
仅有的幸福 2017-06-12 09:24:46
0
1
1235

Der folgende Code stammt aus dem „Unix/Linux Programming Practice Tutorial“. Seine Funktion besteht darin, zwei Threads zu verwenden, um jeweils die Anzahl der Wörter in zwei Dateien zu zählen und die Gesamtzahl im Hauptthread zu berechnen. Unten sehen Sie einen Screenshot des Vorgangs:

Aber nach längerem Lesen ist es immer noch schwierig, die Sperr-, Entsperr- und Bedingungsvariablen im folgenden Code zu verstehen.
Ich möchte fragen:

  1. Wird beim Aufrufen von pthread_cond_wait时会释放互斥锁,然后挂起主线程,并等待条件变量的发生变化,当其他线程调用pthread_cond_signal时,如果互斥锁是被锁住的,那么主线程中的pthread_cond_wait im Hauptthread darauf gewartet, dass der Mutex entsperrt wird, und dann der Mutex gesperrt, bevor zurückgekehrt wird?

  2. Wenn es wie in 1 beschrieben ist, pthread_cond_wait收到了pthread_cond_signal发来的信号,但是未锁定互斥锁之前,又被其他线程抢了先,锁住了互斥锁,那不是pthread_cond_waitmüssen Sie immer noch warten, bis die Mutex-Sperre entsperrt wird?

  3. Wenn möglich, hoffe ich, dass es dabei helfen kann, den Ausführungsprozess dieses Programms zu klären.

Vielen Dank.

#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;
}
仅有的幸福
仅有的幸福

Antworte allen(1)
扔个三星炸死你

没什么复杂的,主线程获得锁后,进入休眠,等一个信号来唤醒它。

pthread_cond_signal就是这个信号

这种锁与别的锁有点不同,其它类型的锁是:线程申请锁,没有得到锁,线程就进入休眠,等待。

这种锁是有锁就休眠,等别的线程叫醒它。

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage