互斥量能够保证在微观层面同一时刻仅有一个线程处理变量,但是不能保证执行顺序,更不能在某一时刻,一个线程通知另一个线程开始开始处理相关任务。
1 条件变量属性类型
#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
typedef union
{
char __size[__SIZEOF_PTHREAD_CONDATTR_T];
int __align;
} pthread_condattr_t;
2 初始化与销毁条件变量属性
int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
pthread_condattr_init
- 以默认值初始化条件变量属性。
- 完成初始化以后,可使用该条件变量属性创建一个或多个条件变量。
- 修改或销毁条件变量不影响使用该属性创建的条件变量。
- 初始化一个已初始化的条件变量属性对象,将导致不确定性行为
pthread_condattr_destroy
- 销毁指定条件变量属性对象
- 执行完成后,条件变量属性对象编程未初始化状态
- 已销毁的条件变量属性对象可以被再次初始化
- 销毁一个已销毁的条件变量属性对象,将导致不确定性行为
3 初始化与销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
初始化与销毁条件变量。
pthread_cond_init
- 初始化一个条件变量
- 如果条件变量属性设置为
NULL
,则以默认的条件变量属性进行初始化 - 执行成功之后,条件变量变为已初始化状态
pthread_cond_destroy
- 销毁指定的条件变量
- 执行成功后,条件变量编程未初始化状态
- 已销毁的条件变量可以被重新初始化
- 销毁一个已销毁的条件变量,将导致不确定性行为
- 销毁一个已初始化且未阻塞任何线程的条件变量是可行的
- 企图销毁一个正在使用的条件变量将导致不确定性行为
4 条件变量之阻塞
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
- 调用这两个函数将导致线程处于阻塞到一个条件变量
- 当收到解锁信号后,阻塞将自动解除
pthread_cond_timedwait
该函数使线程处于阻塞状态到指定的时间,如果在指定的时间内,还未等到信号,则退出等待
5 条件变量之通知
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
-
pthread_cond_signal
解除多个堵塞在同一个条件变量上的线程中的其中一个
-
pthread_cond_broadcast
解除所有阻塞在通过条件变量上的所有线程
6 案例:条件变量的使用
-
源码
线程一启动后进入阻塞状态,等待信号的到来。线程二在启动后,等待5秒后发出信号。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> pthread_mutex_t mutex; pthread_cond_t cond; void *start_routine_01(void *ptr) { printf("进入阻塞状态...\n"); pthread_mutex_lock(&mutex); pthread_cond_wait(&cond, &mutex); printf("获得信号以解除阻塞状态...\n"); pthread_mutex_unlock(&mutex); return (void *)NULL; } void *start_routine_02(void *ptr) { printf("等待5秒后发出解除信号...\n"); sleep(5); pthread_mutex_lock(&mutex); pthread_cond_signal(&cond); printf("解除信号已发出...\n"); pthread_mutex_unlock(&mutex); return (void *)NULL; } int main(int argc, char const *argv[]) { { pthread_mutexattr_t attr; // 定义互斥属性 pthread_mutexattr_init(&attr); // 初始化互斥属性 pthread_mutex_init(&mutex, &attr); // 初始化互斥 pthread_mutexattr_destroy(&attr); // 销毁互斥属性 } { pthread_condattr_t attr; // 定义条件变量属性 pthread_condattr_init(&attr); // 初始化条件变量属性 pthread_cond_init(&cond, &attr); // 初始化条件变量 pthread_condattr_destroy(&attr); // 销毁条件变量属性 } pthread_t thread_id_01; pthread_t thread_id_02; pthread_create(&thread_id_01, NULL, start_routine_01, NULL); pthread_create(&thread_id_01, NULL, start_routine_02, NULL); pthread_join(thread_id_01, NULL); pthread_join(thread_id_02, NULL); pthread_mutex_destroy(&mutex); // 销毁互斥 pthread_cond_destroy(&cond); // 销毁条件变量 exit(EXIT_SUCCESS); }
-
输出
进入阻塞状态…
等待5秒后发出解除信号…
解除信号已发出…
获得信号以解除阻塞状态…