【Linux】多线程_5


九、多线程

6. 条件变量

在多线程编程中,一个或多个线程可能需要等待某个条件的发生,然后才能继续执行,而不是一直忙等。这种等待通常会占用CPU资源。条件变量提供了一种机制,使得线程可以等待某个条件的发生,同时释放CPU资源给其他线程使用。当一个线程需要等待某个条件时,它会先获取互斥锁,然后调用条件变量的等待函数,此时互斥锁会被释放,线程 进入等待队列 。当条件发生时,另一个线程会获取互斥锁,然后调用条件变量的 通知 函数,通知等待的线程条件已经满足。总而言之,条件变量就是一种 等待队列 + 通知唤醒 的机制。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里条件变量的使用方法和互斥锁几乎一样,这里不再描述。
我们来简单使用一下条件变量:
Makefile

testCond:testCond.cc
	g++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:
	rm -f testCond

testCond.cc

#include <iostream>
#include <string>
#include <pthread.h>
#include <vector>
#include <unistd.h>
using namespace std;

// 全局的条件变量
pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;
// 全局的互斥锁
pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;


void* MasterCore(void* args)
{
    sleep(3);
    cout << "Master 线程开始工作了" << endl;
    string name = (const char*)args;
    while (true)
    {
        // 唤醒等待队列头部的线程
        pthread_cond_signal(&gcond);
        cout << "Masther 线程唤醒了一个线程" << endl;

		// 唤醒所有线程
		//pthread_cond_broadcast(&gcond);
        //cout << "Master 线程广播了一个信号, 唤醒了所有线程" << endl;
        sleep(1);
    }
}

void* SlaverCore(void* args)
{
    string name = (const char*)args;
    while (true)
    {
        // 加锁
        pthread_mutex_lock(&gmutex);
        // 等待条件变量
        pthread_cond_wait(&gcond, &gmutex);
        // 解锁
        pthread_mutex_unlock(&gmutex);
        cout << "当前被叫醒的线程是: " << name << endl;
    }
}

void StartMaster(vector<pthread_t>* tidsptr)   
{
    pthread_t tid;
    int n = pthread_create(&tid, nullptr, MasterCore, (void*)"Master Thread");
    if (n == 0)
    {
        cout << "Master Thread Created" << endl;
    }
    tidsptr->emplace_back(tid);
}

void StartSlaver(vector<pthread_t>* tidsptr, int threadnum = 3)
{
    for (int i = 0; i < threadnum; i++)
    {
        char* name = new char[64];
        snprintf(name, 64, "Slaver-%d", i + 1);
        pthread_t tid;
        int n = pthread_create(&tid, nullptr, SlaverCore, name);
        if (n == 0)
        {
            cout << "Slaver Thread " << name << " Created" << endl;
            tidsptr->emplace_back(tid);
        }
    }
}

void WaitThread(vector<pthread_t>& tids)
{
    for (auto& tid : tids)
    {
        pthread_join(tid, nullptr);
    }
}

int main()
{
    vector<pthread_t> tids;
    StartMaster(&tids);
    StartSlaver(&tids, 5);

    WaitThread(tids);
    return 0;
}

在这里插入图片描述

7. 生产者消费者模型

生产者消费者模型是一种常见的并发编程模型,用于解决多个线程之间的协作问题。在生产者消费者模型中,有三种关系:①生产者和生产者之间的互斥关系。②消费者和消费者之间的互斥关系。③生产者和消费者之间的互斥且同步的关系有两种角色:①负责生产数据的生产者。②负责消费数据的消费者有一个交易场所:①提供数据交易的可以短暂存储数据的内存——数据结构对象
在这里插入图片描述

生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。
在这里插入图片描述


未完待续

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值