为什么cond变量不能自动释放?

问题描述

以下代码可在“ Pthreads编程”(O'Reilly媒体)一书中找到:

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

#define TCOUNT 10
#define WATCH_COUNT 12

int count = 0;
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t count_threshold_cv = PTHREAD_COND_INITIALIZER;
int thread_ids[3] = {0,1,2};

void watch_count(int *idp);
void inc_count(int *idp);

extern int
main(void)
{
    pthread_t threads[3];
    pthread_create(&threads[0],NULL,inc_count,&thread_ids[0]);
    pthread_create(&threads[1],&thread_ids[1]);
    pthread_create(&threads[2],watch_count,&thread_ids[2]);

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

    return 0;
}

void watch_count(int *idp)
{
    pthread_mutex_lock(&count_mutex);
    printf("Waiting condition\n");
    while(count <= WATCH_COUNT)
    {
        pthread_cond_wait(&count_threshold_cv,&count_mutex);
        printf("watch_count(): Thread %d,Count is %d\n",*idp,count);
    }
    pthread_mutex_unlock(&count_mutex);
}

void inc_count(int *idp)
{
    for(int i=0; i<TCOUNT; i++)
    {
        pthread_mutex_lock(&count_mutex);
        count++;
        printf("inc_counter(): Thread %d,old count %d,new count %d\n",count-1,count);
        if(count == WATCH_COUNT)
        {
            printf("release\n");
            pthread_cond_signal(&count_threshold_cv);
        }    

        pthread_mutex_unlock(&count_mutex);
    }
}

预期的行为是创建2个线程,该线程将使相同的全局变量“ count”增加到20,当达到12时,它被释放了条件并重新进入watch_counter线程,但是由于某种原因,它没有马上去。

输出如下

inc_counter(): Thread 0,old count 0,new count 1
inc_counter(): Thread 1,old count 1,new count 2
Waiting condition
inc_counter(): Thread 0,old count 2,new count 3
inc_counter(): Thread 1,old count 3,new count 4
inc_counter(): Thread 0,old count 4,new count 5
inc_counter(): Thread 1,old count 5,new count 6
inc_counter(): Thread 0,old count 6,new count 7
inc_counter(): Thread 1,old count 7,new count 8
inc_counter(): Thread 0,old count 8,new count 9
inc_counter(): Thread 1,old count 9,new count 10
inc_counter(): Thread 0,old count 10,new count 11
inc_counter(): Thread 1,old count 11,new count 12
releasing
inc_counter(): Thread 0,old count 12,new count 13
inc_counter(): Thread 1,old count 13,new count 14
watch_count(): Thread 2,Count is 14
inc_counter(): Thread 0,old count 14,new count 15
inc_counter(): Thread 1,old count 15,new count 16
inc_counter(): Thread 0,old count 16,new count 17
inc_counter(): Thread 1,old count 17,new count 18
inc_counter(): Thread 0,old count 18,new count 19
inc_counter(): Thread 1,old count 19,new count 20

有人知道为什么会这样吗?

解决方法

除非强制执行某些特定顺序,否则线程可以按任何顺序执行。

您强制执行的唯一命令是,watch_count小于或等于countWATCH_COUNT无法前进。显然不会发生。

如果您需要执行任何其他排序,则需要编写代码来执行此操作。否则,线程可以任何顺序执行。一个好的实现不会比原来频繁地切换线程,而且您可能会有一个好的实现。

您对它会“马上”使用的期望似乎并不是基于任何东西。其他线程已经在运行,不必等待,那么为什么不继续前进呢?两个inc_count线程已经在运行,它们从不等待任何东西。

pthread_cond_signal函数使当前正在等待条件变量的一个线程停止等待条件变量。在获取互斥锁之前,它仍然无法前进,因为它需要互斥锁来检查是否可以退出while条件。还有其他两个线程争用该互斥对象,并且不能保证它将获胜。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...