//声明全局互斥锁并初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//声明全局条件变量并初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
任务线程代码{
pthread_mutex_lock(&mutex);
if(条件为假)
pthread_cond_wait(&cond, &mutex);//等待时会释放互斥锁,等待完后自动加锁
//访问共享资源....
pthread_mutex_unlock(&mutex);
}
线程调用
pthread_cond_wait
等待时,该接口会释放互斥锁,等待结束后自动加锁
控制线程代码{
if(满足唤醒条件){
pthread_mutex_lock(&mutex);
pthread_cond_signal(cond);
pthread_mutex_unlock(&mutex);
}
}
唤醒操作加锁是为了避免信号丢失
#include <iostream>
#include <unistd.h>
#include <pthread.h>
int cnt = 0;
//声明全局互斥锁并初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
//声明全局条件变量并初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *Count(void * args)
{
//线程分离,无需主线程等待
pthread_detach(pthread_self());
uint64_t number = (uint64_t)args;
std::cout << "pthread: " << number << " create success" << std::endl;
while(true)
{
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
std::cout << "pthread: " << number << " , cnt: " << cnt++ << std::endl;
pthread_mutex_unlock(&mutex);
}
}
int main()
{
for(uint64_t i = 0; i < 4; i++)
{
pthread_t tid;
pthread_create(&tid, nullptr, Count, (void*)i);
usleep(1000);
}
sleep(3);
std::cout << "main thread ctrl begin: " << std::endl;
while(true)
{
sleep(1);
//唤醒在cond的等待队列中等待的一个线程,默认都是第一个
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
//按顺序唤醒在cond的等待队列中的所有线程
//pthread_cond_broadcast(&cond);
std::cout << "signal one thread..." << std::endl;
}
return 0;
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
#pragma once
#include <iostream>
#include <vector>
#include <semaphore.h>
#include <pthread.h>
//环形队列默认容量
const static int defaultcap = 5;
template<class T>
class RingQueue{
private:
std::vector<T> ringqueue_;
int cap_; //容器的容量
int c_step_; // 消费者环形队列指针
int p_step_; // 生产者环形队列指针
sem_t cdata_sem_; // 消费者的数据资源
sem_t pspace_sem_; // 生产者的空间资源
pthread_mutex_t c_mutex_; //消费者与消费者之间的互斥锁
pthread_mutex_t p_mutex_; //生产者与生产者之间的互斥锁
public:
RingQueue(int cap = defaultcap)
:ringqueue_(cap), cap_(cap), c_step_(0), p_step_(0)
{
//初始化生产者和消费者的信号量-->消费者一开始没有信号量资源,生产者一开始具有最多的空间资源
sem_init(&cdata_sem_, 0, 0);
sem_init(&pspace_sem_, 0, cap);
pthread_mutex_init(&c_mutex_, nullptr);
pthread_mutex_init(&p_mutex_, nullptr);
}
~RingQueue()
{
sem_destroy(&cdata_sem_);
sem_destroy(&pspace_sem_);
pthread_mutex_destroy(&c_mutex_);
pthread_mutex_destroy(&p_mutex_);
}
//信号量的资源状态可以区分队列的空和满
void Push(const T &in)
{
//生产者等待空间资源
sem_wait(&pspace_sem_);
pthread_mutex_lock(&p_mutex_);
ringqueue_[p_step_] = in;
p_step_++;
p_step_ %= cap_;
pthread_mutex_unlock(&p_mutex_);
//生产完数据后增加消费者的信号量资源
sem_post(&cdata_sem_);
}
void Pop(T *out)
{
//消费者等待数据资源
sem_wait(&cdata_sem_);
pthread_mutex_lock(&c_mutex_);
*out = ringqueue_[c_step_];
c_step_++;
c_step_ %= cap_;
pthread_mutex_unlock(&c_mutex_);
//消费完数据后增加生产者的信号量资源
sem_post(&pspace_sem_);
}
};