当前位置: 首页 > wzjs >正文

邢台网站制作平台广州市口碑seo推广

邢台网站制作平台,广州市口碑seo推广,windows8 网站建站命令,建设智能家居网站SWOT分析一、线程池 1、线程与进程的区别? 进程是操作系统分配资源的基本单位,线程是操作系统进行CPU调度的单位。 2、线程池的好处? 复用线程资源,减少创建和销毁线程的开销。 3、线程池是什么? 维持管理一定数量线程的…

一、线程池

1、线程与进程的区别?

进程是操作系统分配资源的基本单位,线程是操作系统进行CPU调度的单位。

2、线程池的好处?

复用线程资源,减少创建和销毁线程的开销。

3、线程池是什么?

维持管理一定数量线程的池式结构。

  • 维持:复用资源
  • 管理:线程是参与CPU调度的,如果暂时不需要线程执行,就将其进行休眠,能最大限度的使用资源。
  • 为什么是一定数量,而不是固定数量?:操作系统运行线程是通过CPU的核心去运行的,而CPU的核心数量是有限的,如果线程池中的线程数过多,超过了核心的数量,那么会带来线程切换的开销,反而降低了效率。

4、线程池解决什么问题?

  • 异步执行耗时任务,不过度占用核心线程资源(生产者线程)
    • 耗时:耗时等待(io),耗时计算。
  • 充分利用多核

5、线程池是如何解决问题的?

生产消费模型角度来看:

  • 生产者:核心线程,抛出耗时任务到队列,并唤醒一个休眠线程。
  • 消费者:线程池线程,从队列中取出任务执行;当队列为空时,线程进入休眠状态。
    在这里插入图片描述

二、具体实现

1、面向生产者线程

发布任务到线程池。

void ThreadPoll::Post(std::function<void()> task)
{m_queuePlus->Push(task);
}

2、任务队列

std::queue<std::function<void()>> m_queue;     //任务队列
//但该队列属于临界资源,不利于多线程安全,需要加互斥锁,读写锁等来保证线程安全。

使用阻塞队列,将锁封装在BlockQueue中

BlockQueue<std::function<void()>> m_queue;     //任务队列

3、维持管理一定数量线程

std::vector<std::thread> m_workthreads;     //线程集合

4、线程池线程数量的确定

  • 耗时计算任务:核心线程数 = CPU核心数,因为计算任务是CPU密集型,不会涉及到用户态和内核态的切换,全是用户态执行,所以核心线程数要和CPU的核心数一致。不过这个值是理论值,实际上,需要在该值的基础上,+1,+2,-1,-2等去测试,找到最优值。(测试单位时间内执行任务数来决定)

  • 耗时等待任务:IO密集型任务,IO在Linux下主要分为文件IO和网络IO,因为涉及到用户态和内核态的切换以及IO的等待,所以核心线程数 = 2 * CPU核心数,让一部分线程在等待IO时,能有更多的线程去执行其他任务。同理,也需要测试找到最优值。(测试单位时间内执行任务数来决定)

  • (线程等待时间 + cpu运算时间) * cpu核心线程数 / cpu运算时间 = 线程池最优核心数

5、核心线程抛出任务到队列,并唤醒一个休眠线程

void Push(const T &value) // 入队操作
{std::lock_guard<std::mutex> lock(m_mutex);m_queue.push(value);m_cond.notify_one(); // 唤醒一个等待的线程
}

6、线程池线程从队列中取出任务执行;当队列为空时,线程进入休眠状态。

void ThreadPoll::Worker()
{while (true){std::function<void()> task;if (!m_queuePlus->Pop(task))break;task();}
}bool Pop(T &value) // 出队操作,考虑正常情况与异常情况(队列为空)
{std::unique_lock<std::mutex> lock(m_mutex); // 与lock_guard相比,unique_lock可以延迟锁定,可手动调用unlock,并且同样在析构时自动释放锁。m_cond.wait(lock, [this]{ return !m_queue.empty() || m_nonblock; }); // 若队列为空,则阻塞等待,直到队列不为空或者m_nonblock为true时才继续执行。if (m_queue.empty())return false;value = m_queue.front();m_queue.pop();return true;
}

7、执行完毕,销毁线程

ThreadPoll::~ThreadPoll()
{m_queuePlus->CancelBlock();for (auto &thread : m_workthreads){if (thread.joinable())thread.join();}
}

8、结果:

在这里插入图片描述

9、优化

之前生产者和消费者共用一个队列,并且用一个互斥锁,这样会导致生产者线程和消费者线程都在等待同一个锁;线程数量少,以及任务量少时,感觉不出来,当线程数量变多,任务量多时,效率就会变得低下。

  • 优化方案:生产者对应生产者队列,消费者对应消费者队列。
//在之前阻塞队列里面封装了两个队列,一个生产者队列和一个消费者队列,两把互斥锁,一个生产者队列对应一把锁,一个消费者队列对应一把锁。
std::queue<T> prod_queue_;
std::queue<T> cons_queue_;
std::mutex prod_mutex_;
std::mutex cons_mutex_;int SwapQueue()
{std::unique_lock<std::mutex> lock(m_prod_mutex); // 与lock_guard相比,unique_lock可以延迟锁定,可手动调用unlock,并且同样在析构时自动释放锁。m_cond.wait(lock, [this]{return !m_prod_queue.empty() || m_nonblock; }); // 若队列为空,则阻塞等待,直到队列不为空或者m_nonblock为true时才继续执行。std::swap(m_prod_queue, m_cons_queue);return m_cons_queue.size();
}

在这里插入图片描述

三、总结:

  1. 进程与线程的关系

    • 进程作为操作系统资源分配的基本单位
    • 线程作为CPU调度的基本执行单元
  2. 线程池的核心优势

    • 实现线程资源的高效复用
    • 显著降低频繁创建和销毁线程的系统开销
  3. 线程池的设计原则

    • 采用池化技术管理固定数量的线程
    • 遵循"适量最优"原则,而非盲目增加线程数量
  4. 线程池的核心价值

    • 充分发挥多核CPU的计算优势
    • 实现主线程与耗时任务的异步解耦执行

四、问题:

1、为什么使用队列?

队列是一种双端口操作的数据结构。

  • 职责:生产者对应一个端口,消费者对应另一个端口。
  • 操作队列的时间复杂度为O(1),而vector为O(n),后续加锁灵活。

代码链接:
Code
0voice·Github

http://www.dtcms.com/wzjs/196915.html

相关文章:

  • 网站建设建站网十八未成年禁用免费app
  • 食品公司湖南专业关键词优化
  • 电影网站怎么做laravel竞价推广代运营企业
  • wordpress索引国外seo网站
  • 从该网站复制嵌入代码怎么做关键词seo排名优化推荐
  • 一般网站的后台怎么做的发帖秒收录的网站
  • 哪个网站有淘宝做图的素材百度搜索引擎入口官网
  • 对网站建设过程网络推广方案的基本思路
  • 国家住房和城乡建设网站淘宝seo搜索引擎原理
  • saas建站平台有哪些域名排名查询
  • 制作营销网站模板seo怎么学
  • 成都哪家做网站比较好谷歌seo排名优化服务
  • 做视频开头动画网站互联网营销师考试题及答案
  • swf格式网站链接怎样做企业培训课程推荐
  • 帮人做网站收费合法吗哈尔滨seo优化软件
  • 西昌市住房与城乡建设厅网站电商关键词查询工具
  • 武汉网站建设报价百度竞价推广培训
  • 网站有什么类型投百度做广告效果怎么样
  • photoshop官网入口百度刷seo关键词排名
  • wordpress支持建多个站点吗太原seo
  • 网站上做值机的app惠东seo公司
  • 湖南自考网站建设与管理搜索引擎优化的英语简称
  • 哪些ppt网站是免费的软文拟发布的平台与板块
  • 太原模板建站系统网站运营优化培训
  • 如何做网站服务器西安关键词排名推广
  • wordpress 建站后端seo超级外链发布
  • 南充哪里做网站开发外包网站
  • 音乐网站毕业设计代码2024年重大新闻简短
  • 莱州教研室网站沈阳优化推广哪家好
  • 索菲亚全屋定制seo全称