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

网站建设公司厦门新闻稿发布平台

网站建设公司厦门,新闻稿发布平台,网站建设分金手指专业二七,xp asp 网站建设1.如果用户提交任务都用一个类是不是比较麻烦?能不能用函数 作为用户来说,确实我想使用线程池,还要创建一个类,那样可太累了,所以我想直接放入函数就能运行,比如 这样使用是不是更加方便呢,但是…

1.如果用户提交任务都用一个类是不是比较麻烦?能不能用函数

作为用户来说,确实我想使用线程池,还要创建一个类,那样可太累了,所以我想直接放入函数就能运行,比如

这样使用是不是更加方便呢,但是具体怎么实现呢?

这里我们可以看到后面的两个参数是这个函数的两个形参可以想到模板参数

下面给出完整代码

 template<typename Func, typename... Args>auto submitTask(Func&& func, Args&&... args) -> std::future<decltype(func(args...))>{if (!isPoolRunning_) {std::cerr << "Thread pool is shutdown, cannot submit task." << std::endl;using RType = decltype(func(args...));auto dummyTask = std::make_shared<std::packaged_task<RType()>>([]() -> RType { return RType(); });(*dummyTask)();return dummyTask->get_future();}// 打包任务,放入任务队列里面using RType = decltype(func(args...));auto task = std::make_shared<std::packaged_task<RType()>>(std::bind(std::forward<Func>(func), std::forward<Args>(args)...));std::future<RType> result = task->get_future();// 获取锁std::unique_lock<std::mutex> lock(taskQueMtx_);// 用户提交任务,最长不能阻塞超过1s,否则判断提交任务失败,返回if (!notFull_.wait_for(lock, std::chrono::seconds(1), [&] {return taskQue_.size() < static_cast<size_t>(taskQueMaxThreshHold_);})) {// 表示notFull_等待1s种,条件依然没有满足std::cerr << "task queue is full, submit task fail." << std::endl;auto dummyTask = std::make_shared<std::packaged_task<RType()>>([]() -> RType { return RType(); });(*dummyTask)();return dummyTask->get_future();}// 如果有空余,把任务放入任务队列中taskQue_.emplace([task]() { (*task)(); });taskSize_++;// 因为新放了任务,任务队列肯定不空了,在notEmpty_上进行通知,赶快分配线程执行任务notEmpty_.notify_all();// cached模式 任务处理比较紧急 场景:小而快的任务 需要根据任务数量和空闲线程的数量,判断是否需要创建新的线程出来if (poolMode_ == PoolMode::MODE_CACHED&& taskSize_ > idleThreadSize_&& curThreadSize_ < threadSizeThreshHold_){std::cout << ">>> create new thread..." << std::endl;// 创建新的线程对象auto ptr = std::make_unique<Thread>(std::bind(&ThreadPool::threadFunc, this, std::placeholders::_1));int threadId = ptr->getId();threads_.emplace(threadId, std::move(ptr));// 启动线程threads_[threadId]->start();// 修改线程个数相关的变量curThreadSize_++;idleThreadSize_++;}// 返回任务的Result对象return result;}

这里的     auto submitTask(Func&& func, Args&&... args) -> std::future<decltype(func(args...))>

  • typename Func:这是一个模板类型参数,表示传入的任务函数的类型。Func 可以是任何可调用对象,如普通函数、函数指针、成员函数指针、lambda 表达式、std::function 对象等。
  • typename... Args:这是一个可变参数模板,... 表示可以接受任意数量和类型的参数。Args 是这些参数的类型集合。

所以这里和我们调用的形式刚刚好,这里用了引用折叠,参数会被完美转发给任务函数。

  • decltype(func(args...))decltype 是 C++ 的一个类型推导关键字,用于在编译时推导表达式的类型。func(args...) 表示调用任务函数 func 并传入参数 args...decltype(func(args...)) 会推导出这个调用的返回类型。因此,std::future<decltype(func(args...))> 表示返回一个 std::future 对象,该对象可以获取任务函数的返回结果。

这里采用了异步的方式,和我们之前的使用大同小异,这里显得更加方便,同时异步的方式可以获取抛异常,我们之前如果获取到其他的值也直接放回了

if (!isPoolRunning_) {std::cerr << "Thread pool is shutdown, cannot submit task." << std::endl;using RType = decltype(func(args...));auto dummyTask = std::make_shared<std::packaged_task<RType()>>([]() -> RType { return RType(); });(*dummyTask)();return dummyTask->get_future();
}

对于这段代码来说,如果不能运行了,就返回一个空对象出去,这里是通过packaged_task这个和futuer搭配使用,它的get_futuer会返回一个futuer对象

// 打包任务,放入任务队列里面
using RType = decltype(func(args...));
auto task = std::make_shared<std::packaged_task<RType()>>(std::bind(std::forward<Func>(func), std::forward<Args>(args)...)
);
std::future<RType> result = task->get_future();

这里就是如果不是空,那么肯定是有参数的,那么这里就需要把参数绑定到函数中,所以哟用了bind函数

同时使用了完美转发保留了参数的左值还是右值属性 

这里的  std::future<RType> result = task->get_future();j仅仅是获取一个对象,并没有执行任务

2.线程池的优雅停止

这里因为想到了如果我们在使用线程池,任务都完成了,我想把线程池通过一个信号把它结束,或者它在运行我一样也想结束它,那么就得优雅停止下来,不然整个程序就异常终止了,可能会有内存泄漏

怎么设计呢?,这里我使用了一个shutdown函数,用户自己调用,就可以实现线程池的优雅停止

这里是使用了shutdonwn()的,可以看到下面还有三个任务,值都是0

如果不使用的话

每个任务都会执行完毕 

 void shutdown(bool wait = true){{std::unique_lock<std::mutex> lock(taskQueMtx_);if (!isPoolRunning_) return;isPoolRunning_ = false;// 等待所有任务完成if (wait) {while (taskSize_ > 0 || executingTaskCount_ > 0) {taskFinished_.wait(lock);}}// 清空队列while (!taskQue_.empty()){taskQue_.pop();taskSize_--;}notEmpty_.notify_all();}std::unique_lock<std::mutex> lock(taskQueMtx_);exitCond_.wait(lock, [this] { return threads_.empty(); });}

这是这个函数的主要设计

这里用了一个wait,如果直接调用,那么就会是true,这里加了一个任务完成的原子类型,executingTaskCount_ 如果任务或者没有执行的任务那么直接往下走,如果有,那么就等待,线程执行一个任务就会检查是不是为0,如果是0就通知taskFinished,拿到锁然后清空任务队列,通知所有线程,释放锁,这里各个线程看到线程池的isPoolRunning_ 是false就会知道关闭了,就会退出线程队列,这里会等待所有线程退出,然后结束shutdown函数,这样就实现了优雅停止

3.收尾

其实里面还有很多细节的改动,比如任务队列的包装什么的,但是这是两个比较大的改动,这里其实还有其他地方可以改动,比如很多地方可以用到c++20的语法,把该项目彻底改成c++20的项目,还有就是固定模式和动态变化的模式可以融合起来,这样省去了使用的麻烦,就加一个条件就行了,

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

相关文章:

  • 旅游网站怎么建设百度安装免费下载
  • 网站开发如何做下载支付郑州网络推广哪个好
  • 青岛建网站的公司app推广接单渠道
  • 域名备案后怎样做网站网站检测工具
  • 企业网站建设与管理试题小说排行榜
  • 阿里巴巴做网站吗有哪些可以免费推广的平台
  • 宁波市建设局官网东莞做网站优化
  • 网站建设什么软件seo搜索优化专员
  • 网站设置不安全seo技术服务外包公司
  • 专业知识企业站seo价格
  • wordpress的tag链接url深圳seo外包
  • 绍兴网站制作报价百度竞价排名榜
  • wordpress添加注册页面seo发包技术教程
  • 网站会员注册怎么做天津seo标准
  • 如何做网站流量分析网络营销课程培训
  • 做创意美食的视频网站有哪些做公司网站需要多少钱
  • 做商城网站需要在北京注册公司吗seo是什么意思呢
  • 类似于微博网站怎么做百度图片搜索
  • 小米路由器3做网站磁力搜索器在线
  • 西安网站建设公司排名志鸿优化网官网
  • 网站的建设属于无形资产吗关键词优化收费标准
  • 奢侈品网站建设方案聊城网站开发
  • 即墨区城乡建设局网站seo长尾关键词
  • 3d web做的网站中国营销网站
  • 软件商店vivo官方下载武汉seo排名公司
  • winmag wordpressseo关键词优化指南
  • 完美政府网站管理系统 漏洞广州网站优化公司排名
  • 郑州做网站公司yooker免费网站建设模板
  • 动画素材网站网络广告投放渠道有哪些
  • 企业信息填报系统青岛百度推广优化