目录

  • 一、学习的知识点
    • 有了互斥锁 为什么还要条件变量
      • 1 互斥锁
    • 实际应用把服务器分为两个进程
      • 1.前置服务器
      • 1.1方案1 来一个客户端开一个线程
      • 1.2方案2 线程池
      • 2.后置服务器
  • 二、上课没有听懂或者没有理解的地方
  • 三、当天学习的收获

一、学习的知识点

有了互斥锁 为什么还要条件变量

1 互斥锁

互斥量(mutex)从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁以后,任何其他试图再次对互斥锁加锁的线程将会阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥锁加锁,其他线程将会看到互斥锁依然被锁住,只能回去再次等待它重新变为可用。
需要注意的是,条件变量需要配合互斥锁来使用:
为什么要与pthread_mutex 一起使用呢? 这是为了应对 线程1在调用pthread_cond_wait()但线程1还没有进入wait cond的状态的时候,此时线程2调用了 cond_singal 的情况。 如果不用mutex锁的话,这个cond_singal就丢失了。加了锁的情况是,线程2必须等到 mutex 被释放(也就是 pthread_cod_wait() 释放锁并进入wait_cond状态 ,此时线程2上锁) 的时候才能调用cond_singal.

简而言之就是,在thread 1 call pthread_cond_wait() 的时刻到 thread 1真正进入 wait 状态时,是存在着时间差的。如果在这段时间差内 thread2 调用了 pthread_cond_signal() 那这个 signal 信号就丢失了。给 wait 加锁可以防止同时有另一个线程在 signal。

实际应用把服务器分为两个进程

1.前置服务器

  1. 接收客户端的消息 -》 写到共享内存
  2. 发送消息给后置服务器 -》通知后置服务器取数据

1.1方案1 来一个客户端开一个线程

如果一个任务处理一个线程,一个线程处理完一个任务就结束,那么频繁接入任务就要频繁创建线程,比较耗时间.
优点:简单粗暴、奢侈
缺点:奢侈
此方案适合 计算密集型任务

1.2方案2 线程池

直接开启多个线程,等待任务接入。
一个线程处理完一个任务,继续处理下一个任务。
优点:利用率高
缺点:任务的队列:缓冲
如果任务的时间长,此方案不合适,此方案适合 I/O密集型任务

  1. 任务类
class CTask
{public:CTask() {};void run() { cout << num << "is run" << endl; };int num;CTask(int i) { num = i; };
private:
};
  1. 线程池结构体
typedef struct thread_pool
{pthread_cond_t cond;pthread_mutex_t mutex;int idle;//当前空闲线程的数量, 如果空闲线程 》 0 我就可以唤醒 如果没有空闲线程 创建新线程int count;//当前有多少前程queue<CTask*> task;//栈 任务队列
}THREAD_POOL_T;
  1. 线程池结构体初始化函数 初始化线程池结构体 创建空闲线程
void thread_pool_init(THREAD_POOL_T* pool,int i)
{pthread_cond_init(&pool->cond, NULL);//初始化条件变量pthread_mutex_init(&pool->mutex, NULL);//初始化锁pool->idle = 0; //空闲线程数pool->count = i; //总线程个数for (int i = 0; i < pool->count; ++i){pthread_t tid;pthread_create(&tid, NULL, start_routine, pool);}
}
  1. 线程池添加任务函数
void thread_pool_add_task(THREAD_POOL_T* pool, CTask* t)
{pthread_mutex_lock(&pool->mutex); //加锁 放置很多线程同时存任务pool->task.push(t); //把任务添加到线程池的队列//有?  先去判断pool里面有没有空闲的线程 //判断有没有空闲线程 如果有 就唤醒线程if (pool->idle > 0){pthread_cond_signal(&pool->cond); //通知睡眠的进程 如果线程在忙 则无法唤醒}pthread_mutex_unlock(&pool->mutex);}
  1. 线程回调函数
void* start_routine(void* arg)
{THREAD_POOL_T* pool = (THREAD_POOL_T*)arg;while (1){pthread_mutex_lock(&pool->mutex); //加锁 放置很多线程同时取任务pool->idle++; //进入线程 还未做任务空闲线程+1//创建完成之后,目标是去执行线程池任务//有任务和没任务的情况//判断队列是否为空if (pool->task.empty()) //没任务{//没任务就阻塞在此  等待被唤醒cout << "thread wait..." << pthread_self() << endl;pthread_cond_wait(&pool->cond, &pool->mutex);//条件变量//等待被唤醒 被唤醒后返回 同时上锁cout << "wake up..." << pthread_self() << endl;}//有任务 取任务pool->idle--; //空闲线程 -1CTask* t = pool->task.front();pool->task.pop();pthread_mutex_unlock(&pool->mutex);t->run();}return NULL;
}
  1. 主函数
int main()
{THREAD_POOL_T pool;//线程池结构体thread_pool_init(&pool,5); //线程池初始化初始化while (getchar()){cout << "into" << endl;for (int i = 0; i < 10; ++i){CTask* t = new CTask();thread_pool_add_task(&pool, t); //添加任务队列、唤醒或创建线程}}return 0;
}

2.后置服务器

  1. 收到信号,从共享内存取数据进行处理
  2. 处理好的数据写入共享内存 通知前置服务器取数据

二、上课没有听懂或者没有理解的地方

三、当天学习的收获

210228Linux 条件变量 线程池相关推荐

  1. 【C++ 语言】线程安全队列 ( 条件变量 | 线程调度 )

    文章目录 I . 线程简单使用 II . 互斥锁 III . 条件变量 线程同步 IV . 完整代码示例 006_ThreadSafeQueue.h 006_ThreadSafeQueue.cpp S ...

  2. Linux 多线程(二)线程安全:线程安全、互斥与互斥锁、死锁、同步与条件变量

    线程安全 互斥 死锁 同步 线程安全 所谓线程安全,其实就是当多个线程对临界资源进行争抢访问的时,不会造成数据二义或者逻辑混乱的情况(通常情况下对全局变量和静态变量进行操作时在会出现) 常见的线程安全 ...

  3. 腾讯面试题Java 并发包之线程池综述

    Java 并发包之线程池综述 ■ 线程池的创建 在Java中,您可以通过调整-Xss参数来调节每个线程栈的大小(64bit系统默认1024KB),当减小该值时意味着可以创建更多的线程数,但问题是JVM ...

  4. 线程池的使用(线程池重点解析)

    我们有两种常见的创建线程的方法,一种是继承Thread类,一种是实现Runnable的接口,Thread类其实也是实现了Runnable接口.但是我们创建这两种线程在运行结束后都会被虚拟机销毁,如果线 ...

  5. 吐血整理:Java线程池源码分析(基于JDK1.8建议收藏)

    文章目录 一.引言 二.线程池的参数介绍 1.ThreadPoolExecutor的UML图 三.线程池的使用 1.线程池的工作原理 2.线程池类型 2.1.newCachedThreadPool使用 ...

  6. 【C++ 并发 线程池设计】深入理解C++线程池:设计、实现与应用

    目录标题 1. 引言 2. 线程池类设计 2.1 线程池类的主要成员变量 2.2 线程池类的构造函数和析构函数 3. 线程池任务的添加与执行 3.1 如何添加任务到线程池 3.2 如何在线程池中执行任 ...

  7. JAVA线程池(ThreadPoolExecutor)源码分析

    JAVA5提供了多种类型的线程池,如果你对这些线程池的特点以及类型不太熟悉或者非常熟悉,请帮忙看看这篇文章(顺便帮忙解决里面存在的问题,谢谢!):     http://xtu-xiaoxin.ite ...

  8. 面试官:如何评估一个线程池需要设置多少个线程

    作者 | 丁威       责编 | 欧阳姝黎 见字如面,我是威哥,一个从普通二本院校毕业,从未曾接触分布式.微服务.高并发到通过技术分享实现职场蜕变,成长为 RocketMQ 社区优秀布道师.大厂资 ...

  9. 线程池中使用条件变量和信号量的性能比较

    2019独角兽企业重金招聘Python工程师标准>>> 面试的时候经常被问到互斥量,条件变量和信号量之间的问题.比如前几天华为面试就被问到互斥量和信号量的区别,说到互斥量也可以使用一 ...

最新文章

  1. 这几款嵌入式软件测试工具,好用到起飞~
  2. 进军“手机照相馆”:京东要和3C厂商干什么?
  3. WCF入门(八)——异常处理2
  4. 优化你的DiscuzNT3.0,让它跑起来(4)asp.net 缓存和死锁
  5. 9-21 调试javaweb 数据库连接感想
  6. 非常使用的mongodb的聚合函数(使用SpringDataMongoDb)
  7. 【python写一个无限弹窗】
  8. 计算机网络校园网网络设计报告,计算机网络课程设计报告-校园网的组建和应用...
  9. 微信小程序分享给朋友和分享到朋友圈
  10. 【Python】Time模块 ValueError: unconverted data remains: UnicodeEncodeError:
  11. java resource文件_利用java如何实现读取resource目录下文件
  12. 普适计算的六大必备条件
  13. 《现代控制理论》第四章
  14. freecommander 快捷键列表 zz
  15. TO_DATE使用詳解
  16. 使用Matlab和Minepy工具箱做变量的互信息MIC (maximal information coefficient ) 分析
  17. [转]银监会紧急澄清:二套房贷首付六成报道不实
  18. 51单片机开发入门(3)-IO口应用
  19. 利用爬虫去除acg视频软件广告
  20. 读取统计微信捐款(matlab)

热门文章

  1. yslow客户端性能测试
  2. es6基础0x012:Map
  3. Mac下显示隐藏文件
  4. android 开发 命名规范
  5. Singleton设计模式(单实例)
  6. [原]动态打jar包程序,可用于手机图片音乐游戏的动态打包
  7. MySQL服务的启动与停止-使用命令行工具
  8. SpringAMQP--DirectExchange
  9. 认识微服务-服务架构演变
  10. AIO(Asynchronous IO)基本原理