条件变量本身不是锁!但它也可以造成线程阻塞。通常与互斥锁配合使用。给多线程提供一个会合的场所。
使用STL标准库queue队列
入队—模仿生产
出队—模仿消费
pthread_cond_wait函数
阻塞等待一个条件变量
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
函数作用:
1.阻塞等待条件变量cond(参1)满足
2.释放已掌握的互斥锁(解锁互斥量)相当于pthread_mutex_unlock(&mutex);
1.2.两步为一个原子操作。
3.当被唤醒,pthread_cond_wait函数返回时,解除阻塞并重新申请获取互斥锁pthread_mutex_lock(&mutex);
pthread_cond_signal函数
唤醒至少一个阻塞在条件变量上的线程
int pthread_cond_signal(pthread_cond_t *cond);
pthread_cond_broadcast函数
唤醒全部阻塞在条件变量上的线程
int pthread_cond_broadcast(pthread_cond_t *cond);
一个生产者,一个消费者
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <queue>
using namespace std;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
queue<int>my_Queue; //产品队列
void *consumer(void *p)
{
for (;;) {
pthread_mutex_lock(&lock);
while (my_Queue.empty()) {
pthread_cond_wait(&has_product, &lock);
}
//模拟消费掉一个产品
int num=my_Queue.front(); //获取队头元素
my_Queue.pop();//出队
pthread_mutex_unlock(&lock);
printf("-Consume ---%d, now total = %lu\n", num,my_Queue.size());
sleep(rand() % 2+1);
}
}
void *producer(void *p)
{
while (1) {
int num= rand() % 1000 + 1; //模拟生产一个产品
pthread_mutex_lock(&lock);
my_Queue.push (num); //产品入队
pthread_mutex_unlock(&lock);
printf("-Produce ---%d, now total = %lu\n", num,my_Queue.size());
pthread_cond_signal(&has_product); //将等待在该条件变量上的一个线程唤醒
sleep(rand() % 2);
}
}
int main(int argc, char *argv[])
{
pthread_t pid, cid;
srand(time(NULL));
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}
编译输出
g++ s.cpp -pthread
./a.out
-Produce —77, now total = 1
-Consume —77, now total = 0
-Produce —140, now total = 1
-Consume —140, now total = 0
-Produce —231, now total = 1
-Produce —343, now total = 2
-Consume —231, now total = 1
-Produce —426, now total = 2
-Produce —691, now total = 3
-Consume —343, now total = 2
-Produce —414, now total = 3
-Consume —426, now total = 2
-Produce —640, now total = 3
-Produce —357, now total = 4
-Consume —691, now total = 3
-Produce —905, now total = 4
^C
一个生产者,3个消费者
clude <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <queue>
using namespace std;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
queue<int>my_Queue; //产品队列
void *consumer(void *p)
{
for (;;) {
pthread_mutex_lock(&lock);
while (my_Queue.empty()) {
pthread_cond_wait(&has_product, &lock);
}
//模拟消费掉一个产品
int num=my_Queue.front(); //获取队头元素
my_Queue.pop();//出队
pthread_mutex_unlock(&lock);
printf("-Consume ---%d, thread id = %lu, now total num = %lu\n", num,pthread_self(),my_Queue.size());//打印消费的产品,消费者线程id,剩余产品数量
sleep(rand() % 2+2);
}
}
void *producer(void *p)
{
while (1) {
int num= rand() % 1000 + 1; //模拟生产一个产品
pthread_mutex_lock(&lock);
my_Queue.push (num); //产品入队
pthread_mutex_unlock(&lock);
printf("-Produce ---%d, now total num = %lu\n", num,my_Queue.size());
pthread_cond_broadcast(&has_product); //将等待在该条件变量上的所有线程唤醒
sleep(rand() % 2);
}
}
int main(int argc, char *argv[])
{
int i;
pthread_t pid, cid[3];
srand(time(NULL));
pthread_create(&pid, NULL, producer, NULL);
for(i=0;i<3;i++)
pthread_create(&cid[i], NULL, consumer, NULL);
pthread_join(pid, NULL);
for(i=0;i<3;i++)
pthread_join(cid[i], NULL);
return 0;
}
g++ cond2.c -pthread
./a.out
-Produce —305, now total num = 1
-Consume —305, thread id = 140698680510208, now total num = 0
-Produce —219, now total num = 1
-Consume —219, thread id = 140698688902912, now total num = 0
-Produce —297, now total num = 1
-Consume —297, thread id = 140698697295616, now total num = 0
-Produce —544, now total num = 1
-Produce —307, now total num = 2
-Consume —544, thread id = 140698680510208, now total num = 1
-Produce —163, now total num = 2
-Produce —997, now total num = 3
-Produce —829, now total num = 4
-Produce —829, now total num = 5
-Consume —307, thread id = 140698688902912, now total num = 4
-Consume —163, thread id = 140698697295616, now total num = 3
-Produce —850, now total num = 4
-Consume —997, thread id = 140698680510208, now total num = 3
-Produce —95, now total num = 4
-Produce —802, now total num = 5
-Consume —829, thread id = 140698688902912, now total num = 4
-Consume —829, thread id = 140698697295616, now total num = 3
-Produce —110, now total num = 4
-Produce —452, now total num = 5
-Produce —827, now total num = 6
^C
本文介绍了条件变量pthread_cond_t在多线程同步中的作用,它不作为锁但可以导致线程阻塞。结合互斥锁使用,用于线程间会合。通过示例展示了如何使用条件变量实现生产者消费者模型,详细解析了pthread_cond_wait、pthread_cond_signal和pthread_cond_broadcast函数的工作原理,并给出了不同数量生产者和消费者运行的示例输出。
751

被折叠的 条评论
为什么被折叠?



