你在学习linux多线程的时候,往往会遇到一些问题。今天我来讲一下pthread_cond_wait这个函数。
API定义如下:
你在学习条件变量,会遇到pthread_cond_wait这个函数,但是你可能对这个函数的实现不是很了解,因为我看了很多资料,包括书上和网上的资料,大部分给出的是如下的解释:
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
这种解释很官方,但是难以理解。
下面是一个例子,我们先来看看。(某本书上的例子)
/*
A simple thread program,just do a sum.
compile:
gcc couter.c -o couter -lpthread
Copyright (C) 2006, Li Suke, School of Software, Beijing University
This is free software; you can redistribute it and/or
modify it freely.
This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define THREAD_NUMBER 2
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* thread1(void *arg)
{
pthread_mutex_lock(&mutex);
printf("thread1 locked the mutex\n");
printf("thread1 is waiting for condition signal...\n");
pthread_cond_wait(&cond, &mutex);
printf("thread1 received condition signal!\n");
pthread_mutex_unlock(&mutex);
printf("thread1 unlocked the mutex\n");
pthread_exit(0);
}
void* thread2(void *arg)
{
int i = 0;
struct timeval old, new;
gettimeofday(&old);
new = old;
pthread_mutex_lock(&mutex);
printf("thread2 locked the mutex\n");
while (new.tv_sec - old.tv_sec < 5) {
sleep(1);
gettimeofday(&new);
i++;
printf("thread2 sleep %d seconds\n", i);
}
printf("thread1 calls pthread_cond_signal...\n");
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
printf("thread2 unlocked the mutex\n");
pthread_exit(0);
}
int main(int argc, char *argv[])
{
int i;
int ret_val;
pthread_t pt[THREAD_NUMBER];
ret_val = pthread_create(&pt[0], NULL, thread1, NULL);
if (ret_val != 0 ) {
printf("pthread_create error!\n");
exit(1);
}
ret_val = pthread_create(&pt[1], NULL, thread2, NULL);
if (ret_val != 0 ) {
printf("pthread_create error!\n");
exit(1);
}
for (i = 0; i < THREAD_NUMBER; i++) {
ret_val = pthread_join(pt[i], NULL);
if (ret_val != 0) {
printf("pthread_join error!\n");
exit(1);
}
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
此例子定义了一个互斥量mutex和一个条件变量cond。
当线程进入thread1时(该例子会先进入thread1线程),首先调用pthread_mutex_lock(&mutex)这个条语句讲互斥量上锁,因此thread2线程会在pthread_mutex_lock(&mutex);这条语句处等待。当thread1线程执行pthread_cond_wait(&cond, &mutex);这条语句时,简单的来说,该函数做了两件事情,1.给mutex解锁,2.阻塞thread1(直到thread2执行完pthread_cond_signal(&cond);和pthread_mutex_unlock(&mutex);这两条语句才会解除,缺一不可)。然后thread2线程执行pthread_mutex_lock(&mutex);,即给mutex上锁,然后一直执行,直到执行完pthread_mutex_unlock(&mutex);这条语句时,thread1线程解除阻塞状态,但是你可要记住了,thread1中的pthread_cond_wait(&cond, &mutex);在解除阻塞的时候其实干了两件事情,1.解除阻塞,2.重新给mutex上锁。不然你可能会陷入误区。
以上是我的理解,请大家批评指教。