如果pthread_cond_wait()与另一个线程竞争会发生什么?

时间:2017-06-10 07:46:47

标签: c linux multithreading

这是一个程序,它的功能是计算两个文件中的单词,包含3个主题(一个是主线程,一个是file1,一个是文件2)。

我知道pthread_cond_wait(&flag, &lock)会在返回之前锁定互斥锁。但是如果另一个线程首先锁定互斥锁会发生什么呢?

在这个程序中:

  1. 主线程调用pthread_cond_wait,它解锁互斥锁。
  2. thread1锁定互斥锁,在执行某些操作后,它会调用pthread_cond_signal
  3. 主线程得到了thread1发送的信号,然后它想锁定互斥锁,但互斥锁被thread1锁定,所以主线程被阻塞。
  4. thread1解锁互斥锁。
  5. 主线程(pthread_cond_wait)现在可以锁定互斥锁并返回。
  6. 但是!此时(第5步),如果另一个线程(比如thread2)在pthread_cond_wait锁定互斥锁之前先锁定互斥锁,会发生什么?主线程仍然被阻止?如果确实如此,那么  这个程序是一个错误的程序,所有的线程(主线程和thread2)都将被阻止。但我已经运行了很多次,它工作得很好。

    更新我的问题:在pthread_cond_wait获取pthread_cond_signal发送的需要互斥锁锁定的信号的时刻与当前时刻之间,其他线程是否会锁定互斥锁pthread_cond_wait锁定互斥锁。

    #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 = '\0';
    
        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;
    }
    

0 个答案:

没有答案