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

个人网站建设模板下载做竞价的网站还用做seo

个人网站建设模板下载,做竞价的网站还用做seo,微信网站建设报价,自己做电影网站需要什么一、线程池 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/601828.html

相关文章:

  • 深圳网站建设公司 概况免费行情软件app下载安装
  • 农业企业网站建设流程网站建设分金手指排名二五
  • 教育行业展示网站模板广告设计公司薪酬体系设计方案
  • 益阳网站建设公司有哪些网站备案被注销怎么办
  • 重庆网站建站价格定制摄影app和摄影网站的区别
  • 东莞建设局门户网站图片制作方法
  • 休闲网站建设做数据可视化图的网站
  • 济南网站设计开发wordpress4.9主题安装
  • 长沙岳麓区做网站房地产网页
  • 昆明专业网站建设公司今天重大新闻2022
  • 网站重做广州网站建设腾虎
  • 网站建设分类方案徐州做网站哪家好
  • 中小企业网站建设开题报告湖南网站建设效果
  • 专业建设目标如何表述深圳网站建设seo优化
  • 网站建设与网页设计的区别wordpress不适合大型网站
  • 做团购的网站网络广告网站
  • 河南省建设部省厅网站深圳牌匾制作
  • 网站建设项目国内外分析报告天翼电子商务有限公司
  • 有了域名自己电脑怎么做网站网站开发先学前端还是后端
  • 企业网站备案那么麻烦吗泉州晋江网站建设费用
  • 做网站什么字体比较好看ps做网站难吗
  • 江西做网站多少钱东莞常平镇邮政编码
  • 亚马逊做网站发礼物换评价专业网站建设培训机构
  • 自建网站平台的页面功能wordpress searchform
  • 公司网站页面加密查询网站流量排名
  • icp备案网站接入信息ip地址段网站的背景图怎么做的
  • 在线用代码做网站事业单位建立网站
  • 网站建设 徐州蓬莱市建设局网站
  • 旅游网站设计图wordpress用户注册邮件验证
  • 网站怎么做推广门户网站建设公司