先来说一下 信号量和条件变量的区别和共同点,很多人容易搞混淆,认为这差不多。
严格说 条件变量主要作用不是处理线程同步的,而是进行线程阻塞操作,如果多个线程使用条件变量会发生 资源混乱。一般结合互斥锁来使用。
比如 达到某个条件 线程阻塞,或者 不满足线程唤起。
信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作。信号量不一定是锁定某一个资源,而是流程上的概念,
共同点:
信号量和条件变量一样用于处理生产者和消费者模型,用于阻塞生产者线程或者消费者线程的运行。
分割线-----------------------------------------------------------------------------------------------------------------------
条件变量:
头文件 #include <pthread.h>
定义:pthread_cond_t cond;
初始化:int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);参数说明:
cond: 条件变量的地址
attr: 条件变量属性,一般使用默认属性,指定为 NULL
销毁:int pthread_cond_destroy(pthread_cond_t *cond);
线程阻塞函数, 哪个线程调用这个函数, 哪个线程就会被阻塞
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
时间设置阻塞函数:
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
唤醒线程:
// 唤醒阻塞在条件变量上的线程, 至少有一个被解除阻塞
int pthread_cond_signal(pthread_cond_t *cond);
// 唤醒阻塞在条件变量上的线程, 被阻塞的线程全部解除阻塞
int pthread_cond_broadcast(pthread_cond_t *cond);
信号量:
头文件:#include <semaphore.h>
定义:sem_t sem;
初始化:
// 初始化信号量/信号灯
int sem_init(sem_t *sem, int pshared, unsigned int value);
销毁:
// 资源释放, 线程销毁之后调用这个函数即可
// 参数 sem 就是 sem_init() 的第一个参数
int sem_destroy(sem_t *sem);
资源消耗:
// 参数 sem 就是 sem_init() 的第一个参数
// 函数被调用sem中的资源就会被消耗1个, 资源数-1
int sem_wait(sem_t *sem);// 参数 sem 就是 sem_init() 的第一个参数
// 函数被调用sem中的资源就会被消耗1个, 资源数-1
int sem_trywait(sem_t *sem);
时间等待
// 表示的时间是从1971.1.1到某个时间点的时间, 总长度使用秒/纳秒表示
struct timespec {
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds [0 .. 999999999] */
};
// 调用该函数线程获取sem中的一个资源,当资源数为0时,线程阻塞,在阻塞abs_timeout对应的时长之后,解除阻塞。
// abs_timeout: 阻塞的时间长度, 单位是s, 是从1970.1.1开始计算的
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
// 调用该函数给sem中的资源数+1
int sem_post(sem_t *sem);
// 查看信号量 sem 中的整形数的当前值, 这个值会被写入到sval指针对应的内存中
// sval是一个传出参数
int sem_getvalue(sem_t *sem, int *sval);