本期研究一下Pthreads的条件变量。从网上找到了一个学习笔记,请看“cnblogs-blueclue's tech blog-POSIX线程库条件变量的使用--Pthreads线程库实例笔记4”。

在windows上测试了一下该代码,稍作改动, 粘贴如下:

其中有几点需要注意:

  1. 延时函数是Sleep(),在头文件<windows.h>中。该函数用于延时某一线程的执行;

  2. 轮询次数设置为while循环的条件,在信号发送和接受函数中,轮询次数应当保持一致;

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

int count = 0;

pthread_cond_t count_threshold_cv;
pthread_mutex_t count_mutex;

void * watch_count(void *t){

    long my_id = (long) t;


    while(count < 15){
        pthread_mutex_lock(&count_mutex);
        printf("Starting watch_count(): thread %ld\n", my_id);
        printf("watch_count(): thread %ld going into wait ...\n", my_id);
        pthread_cond_wait(&count_threshold_cv, &count_mutex);
        /*suspend execution for an interval of time*/
        //Sleep(100000);
        printf("watch_count(): thread %ld condition signal received.\n", my_id);
        printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
        pthread_mutex_unlock(&count_mutex);
    }
    pthread_exit(NULL);
}

void * inc_count(void *t){

    long my_id = (long) t;

    while(count < 15){
        pthread_mutex_lock(&count_mutex);
        count++;
        if(count > 10){
            printf("inc_count(): thread %ld, count = %d Threshold reached", my_id, count);
            pthread_cond_signal(&count_threshold_cv);
            printf("Just sent signal.\n");
        }
        printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", my_id, count);
        pthread_mutex_unlock(&count_mutex);
    }
    pthread_exit(NULL);
}

int main(){
    pthread_t threads[3];
    pthread_mutex_init(&count_mutex, NULL);
    pthread_cond_init(&count_threshold_cv, NULL);

    long t1 = 1, t2 = 2, t3 = 3;
    pthread_create(&threads[0], NULL, watch_count, (void *) t1);
    pthread_create(&threads[1], NULL, inc_count, (void *) t2);
    pthread_create(&threads[2], NULL, inc_count, (void *) t3);

    for(int i = 0; i < 3; i++){
        pthread_join(threads[i], NULL);
    }

    pthread_mutex_destroy(&count_mutex);
    pthread_cond_destroy(&count_threshold_cv);
    pthread_exit(NULL);
    return 0;
}