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

阿里云服务器 多个网站搜索引擎排名google

阿里云服务器 多个网站,搜索引擎排名google,光泽网站建设wzjseo,群晖 做网站1 线程池是什么? 在多任务并发执行的时候往往需要开启很多线程来执行。而一个线程的创建和销毁是需要消耗一部分计算机资源的,而如果一个线程执行任务的资源消耗和创建一个线程的消耗差不多的情况下,那简直太浪费资源了。所以如果有已经创建…

1 线程池是什么?

在多任务并发执行的时候往往需要开启很多线程来执行。而一个线程的创建和销毁是需要消耗一部分计算机资源的,而如果一个线程执行任务的资源消耗和创建一个线程的消耗差不多的情况下,那简直太浪费资源了。所以如果有已经创建好的一堆线程等着执行任务,有任务来了,调用一个线程去执行就可以了,不用重新创建一个线程。这样可以省去很多资源消耗。

而线程池就是创建了若干个等待执行任务的线程的容器。线程池就是一个线程的容器,线程池负责容纳,管理,甚至调度线程的执行和任务的分配(其中线程的调度和任务的分配不一定是由线程池来完成这个根据实现的不同有不同的责任分配)。

线程池的基本运行过程是管理一个任务队列,一个线程队列,然后每次去一个任务分配给一个线程去做,一直这样循环。

2 线程池实现原理

前面说过要在线程池中线程是复用的,而任务是不断更换的。但是这一点在语言层面是不支持的,因为一般的thread都是执行一个固定的task函数,当执行完毕后该线程就结束了,然后销毁。所以如何实现task和thread的分配是一个关键的问题。

这里一般有两种解决办法
1、一种是让每一个线程都执行任务调度函数,循环获取一个task,然后执行。
2、每一个形成处于等待任务状态,另有一个主线程来进行任务调度。

其中第一种方法比较简单,实现起来也非常容易,但是该方法有个缺点就是如果线程比较多的情况下会存在对任务队列访问的竞争,从而降低效率。所以这里以第二种方式实现线程池。

大概规划如下:
1、需要对线程进行封装,做好线程自己的同步。
2、需要一个线程容器,比如队列或者列表之类
3、任务队列,如果有优先级要求的化可以加入优先级评价体系。任务队列是一个典型的生产者和消费者模型。
4、需要一个任务调度线程
5、每个工作线程绑定一个任务,如果没有任务的情况下线程处于阻塞状态。当接受到一个任务后线程唤醒然后执行任务。

3 线程池实现

需要声明的一点是该线程池的实现使用了大量的C++11中的内容,编译器用的是vs2017(对C++11支持比较友好)

其中用到的C++11中的内容有:

1、thread
2、mutex
3、condition_variable
4、atomic

5、unique_lock

 4 使用单例,考虑到线程池全局使用一个

使用单例封装线程池

#ifndef THREAD_POOL_H
#define THREAD_POOL_H#include <vector>
#include <queue>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <future>
#include <functional>
#include <stdexcept>namespace std
{
#define  MAX_THREAD_NUM 256//线程池,可以提交变参函数或拉姆达表达式的匿名函数执行,可以获取执行返回值//不支持类成员函数, 支持类静态成员函数或全局函数,Opteron()函数等class ThreadPool{protected:/* We need access to the mutex in AddWork, and the variable is only* visible in .cxx file, so this method returns it. *//* We need access to the mutex in AddWork, and the variable is only* visible in .cxx file, so this method returns it. */std::mutex &GetMutex();ThreadPool();~ThreadPool()  ;private:using Task = std::function<void()>;std::mutex          m_Mutex;//空闲线程数量std::atomic<int>  idlThrNum;/** This is a list of jobs submitted to the thread pool.* This is the only place where the jobs are submitted.* Filled by AddWork, emptied by ThreadExecute. */std::deque<std::function<void()>> m_WorkQueue;/** When a thread is idle, it is waiting on m_Condition.* AddWork signals it to resume a (random) thread. */std::condition_variable m_Condition;/** Vector to hold all thread handles.* Thread handles are used to delete (join) the threads. */std::vector<std::thread> m_Threads;/* Has destruction started? */std::atomic<bool> m_Stopping = false;/** The continuously running thread function */static voidThreadExecute();/** To lock on the internal variables *///static ThreadPool  m_ThreadPoolInstance;public://void ThreadPool::RemoveInstance();static ThreadPool*GetInstance();void AddThreads(int count);int GetNumberOfCurrentlyIdleThreads();// 提交一个任务// 调用.get()获取返回值会等待任务执行完,获取返回值// 有两种方法可以实现调用类成员,// 一种是使用   bind: .commit(std::bind(&Dog::sayHello, &dog));// 一种是用 mem_fn: .commit(std::mem_fn(&Dog::sayHello), &dog)template <class Function, class... Arguments>autoAddWork(Function && function, Arguments &&... arguments)-> std::future<typename std::result_of<Function(Arguments...)>::type>{if (m_Stopping.load())    // stop == true ??throw std::runtime_error("commit on ThreadPool is stopped.");using return_type = typename std::result_of<Function(Arguments...)>::type;auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<Function>(function), std::forward<Arguments>(arguments)...));std::future<return_type> res = task->get_future();{std::unique_lock<std::mutex> lock(this->GetMutex());m_WorkQueue.emplace_back([task]() { (*task)(); });}m_Condition.notify_one();return res;}//空闲线程数量int idlCount() { return idlThrNum; }};}#endif

CPP

// ThreadPool.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "threadpool.h"#define DEFAULT_THREAD_COUNT 4
namespace std {ThreadPool *ThreadPool::GetInstance(){static ThreadPool g_ThreadPoolInstance;return   &g_ThreadPoolInstance;}ThreadPool::ThreadPool(){for (unsigned int i = 0; i < DEFAULT_THREAD_COUNT; ++i){m_Threads.emplace_back(&ThreadExecute);}}void ThreadPool::AddThreads(int count){std::unique_lock<std::mutex> mutexHolder(m_Mutex);m_Threads.reserve(m_Threads.size() + count);for (unsigned int i = 0; i < count; ++i){m_Threads.emplace_back(&ThreadExecute);}}std::mutex &ThreadPool::GetMutex(){return m_Mutex;}voidThreadPool::ThreadExecute(){// plain pointer does not increase reference countThreadPool * threadPool = GetInstance();while (!threadPool->m_Stopping.load()){std::function<void()> task;{std::unique_lock<std::mutex> mutexHolder(threadPool->m_Mutex);threadPool->m_Condition.wait(mutexHolder,[threadPool] { return threadPool->m_Stopping.load() || !threadPool->m_WorkQueue.empty(); });if (threadPool->m_Stopping.load()&& threadPool->m_WorkQueue.empty()){printf("qq---------------------------ThreadExecute ----------------- exit\n");return;}task = std::move(threadPool->m_WorkQueue.front());threadPool->m_WorkQueue.pop_front();}task(); // execute the task}printf("ww-------------------------------ThreadExecute ----------------- exit\n");}intThreadPool::GetNumberOfCurrentlyIdleThreads()  {std::unique_lock<std::mutex> mutexHolder(m_Mutex);return int(m_Threads.size()) - int(m_WorkQueue.size()); // lousy approximation}ThreadPool:: ~ThreadPool(){m_Stopping.store(true);m_Condition.notify_all(); // 唤醒所有线程执行for (auto & m_Thread : m_Threads){if (m_Thread.joinable())m_Thread.join();}printf("~ThreadPool()---------------------ThreadExecute ----------------- exit\n");}}

使用

// ThreadPool.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "threadpool.h"#include "threadpool.h"
#include <iostream>
using namespace std;
void fun1(int slp)
{printf("  hello, fun1 !  %d\n", std::this_thread::get_id());if (slp>0) {printf(" ======= fun1 sleep %d  =========  %d\n", slp, std::this_thread::get_id());std::this_thread::sleep_for(std::chrono::milliseconds(slp));}
}struct gfun {int operator()(int n) {printf("%d  hello, gfun !  %d\n", n, std::this_thread::get_id());return 42;}
};class A {
public:static int Afun(int n = 0) {   //函数必须是 static 的才能直接使用线程池std::cout << n << "  hello, Afun !  " << std::this_thread::get_id() << std::endl;return n;}static std::string Bfun(int n, std::string str, char c) {std::cout << n << "  hello, Bfun !  " << str.c_str() << "  " << (int)c << "  " << std::this_thread::get_id() << std::endl;return str;}
};int main()
try {ThreadPool * executor = ThreadPool::GetInstance();executor->AddThreads(50);A a;std::future<void> ff = executor->AddWork(fun1, 0);std::future<int> fg = executor->AddWork(gfun{}, 0);std::future<int> gg = executor->AddWork(a.Afun, 9999); //IDE提示错误,但可以编译运行std::future<std::string> gh = executor->AddWork(A::Bfun, 9998, "mult args", 123);std::future<std::string> fh = executor->AddWork([]()->std::string { std::cout << "hello, fh !  " << std::this_thread::get_id() << std::endl; return "hello,fh ret !"; });std::cout << " =======  sleep ========= " << std::this_thread::get_id() << std::endl;std::this_thread::sleep_for(std::chrono::microseconds(90));for (int i = 0; i < 50; i++) {executor->AddWork(fun1, i * 100);}std::cout << " =======  commit all ========= " << std::this_thread::get_id() << " idlsize=" << executor->GetNumberOfCurrentlyIdleThreads() << std::endl;std::cout << " =======  sleep ========= " << std::this_thread::get_id() << std::endl;std::this_thread::sleep_for(std::chrono::seconds(3));ff.get(); //调用.get()获取返回值会等待线程执行完,获取返回值std::cout << fg.get() << "  " << fh.get().c_str() << "  " << std::this_thread::get_id() << std::endl;std::cout << " =======  sleep ========= " << std::this_thread::get_id() << std::endl;std::this_thread::sleep_for(std::chrono::seconds(3));std::cout << " =======  fun1,55 ========= " << std::this_thread::get_id() << std::endl;executor->AddWork(fun1, 55).get();    //调用.get()获取返回值会等待线程执行完std::cout << "end... " << std::this_thread::get_id() << std::endl;//std::threadpool pool(4);//std::vector< std::future<int> > results;//for (int i = 0; i < 8; ++i) {//	results.emplace_back(//		pool.commit([i] {//		std::cout << "hello " << i << std::endl;//		std::this_thread::sleep_for(std::chrono::seconds(1));//		std::cout << "world " << i << std::endl;//		return i*i;//	})//	);//}//std::cout << " =======  commit all2 ========= " << std::this_thread::get_id() << std::endl;//for (auto && result : results)//	std::cout << result.get() << ' ';//std::cout << std::endl;//executor->RemoveInstance();return 0;
}
catch (std::exception& e) {std::cout << "some unhappy happened...  " << std::this_thread::get_id() << e.what() << std::endl;
}

Demo 下载

http://www.hrbkazy.com/news/35778.html

相关文章:

  • 网站定制微安电力案例模板免费下载网站
  • 网站备案是在哪里查百度网址大全下载安装
  • 网站开发属于税务什么类别网站流量监控
  • php网站建设是什么意思图片优化软件
  • 唐山网站制作价格网站怎么优化关键词
  • 网站里的副栏目是什么百度认证官网
  • 网站备案负责人一定要法人网站优化排名金苹果下拉
  • 有什么做户外活动的网站吗排名优化软件
  • 南京自适应网站网店如何做推广
  • 如何做网站新手营销型网站建设步骤
  • ecshop网站搬家全球十大网站排名
  • 专门做进口零食的网站北京关键词快速排名
  • 武汉做网站哪家公司好常用的网络营销推广方法有哪些
  • 天天新品网做网站网站alexa排名查询
  • 豫建设标 网站百度关键字
  • php网站开发技术题目快手作品推广网站
  • 精神文明建设专题网站长春网站排名提升
  • 哪家公司建网站好全国唯一一个没有疫情的城市
  • 石家庄网站开发培训搜索引擎优化指的是什么
  • 建网站没有实体公司能建站吗搜索引擎优化代理
  • 四川省和城乡建设厅网站广告留电话号的网站
  • 代理ip访问网站2023年9月疫情又开始了吗
  • 哪家做网站最便宜济南网站seo
  • 做房间预定网站需要什么软件seo排名怎么样
  • python做网站网站seo优化
  • 做网站大概费用想要导航推广网页怎么做
  • 南充营销型网站建设站长之家seo查找
  • python3做网站教程百度地图推广怎么做的
  • 学做快餐在哪个网站做小程序要多少钱
  • 英文网站推广公司b2b网站大全