并发编程(9)线程池---高级线程管理

       我们通过创建 std::thread 对象来对线程进行管理。在一些情况下,这种方式不可行,因为需要在线程的整个生命周期中对其进行管理,并根据硬件来确定线程数量,等等。另一种情况是,当使用多线程来解决某个问题时,在某个条件达成的时候,可以提前结束。

       所以从管理线程任务的机制,两个角度介绍线程池。

一、简单的线程池

  定义:管理一个任务队列,一个线程队列,然后每次取一个任务分配给一个线程去做,循环往复。作为最简单的线程池,其拥有固定数量的工作线程(通常工作线程数量std::thread::hardware_concurrency() 相同)。当工作需要完成时,可以调用函数将任务挂在任务队列中。每个工作线程都会从任务队列上获取任务,然后执行这个任务,执行完成后再回来获取新的任务。

      简单的线程池:

class thread_pool
{
  std::atomic_bool done;
  thread_safe_queue<std::function<void()> > work_queue; // 1   线程安全队列管理任务队列
  std::vector<std::thread> threads; // 2   工作线程
  join_threads joiner; // 3  来汇聚所有线程
  void worker_thread()
  {
    while(!done) // 4
    {
      std::function<void()> task;
      if(work_queue.try_pop(task)) // 5  从队列上获取任务
      {
        task(); // 6  执行任务,可在此加上线程数目增加语句。完成任务,增加一个空闲线程数目
      }
      else
      {
        std::this_thread::yield(); // 7  让线程休息
      }
    }
  }
public:
  thread_pool():  //列表初始化类
  done(false),joiner(threads)
  {
    unsigned const
    thread_count=std::thread::hardware_concurrency(); // 8 获取硬件支持并发数
    try
    {
      for(unsigned i=0;i<thread_count;++i)
      {
        threads.push_back(
        std::thread(&thread_pool::worker_thread,this)); // 9   线程执行于此,每个线程都会执行获取任务的函数。但是,本简单线程池不支持线程的回收循环利用
      }                                                   //可以,在回收线程那里加上--thread_count;从而可以多次循环
    }
    catch(...)
    {
      done=true; // 10
       throw;
    }
  }
  ~thread_pool()
  {
    done=true; // 11
  }
  template<typename FunctionType>
  void submit(FunctionType f)
  {
    work_queue.push(std::function<void()>(f)); // 12  将函数f包装成一个std::function<void()>实例,推入队列之中
  }
};

CPU密集型的程序要(cpu个数个+1)个线程就行了,I/O密集型,因为I/O操作不需要访问CPU,所以可以创建多个线程(2*NUM_cpu).

另一个思路,先创建一定量的线程,当忙碌线程达到总线程的80%时,创建新的线程。

总之线程池通常适合下面的几个场合: 
(1) 单位时间内处理任务频繁而且任务处理时间短 
(2) 对实时性要求较高。如果接受到任务后在创建线程,可能满足不了实时要求,因此必须采用线程池进行预创建。 
(3) 必须经常面对高突发性事件,比如Web服务器,如果有足球转播,则服务器将产生巨大的冲击。此时如果采取传统方法,则必须不停的大量产生线程,销毁线程。此时采用动态线程池可以避免这种情况的发生。

 

 

 

以后填坑@@//TODO

转载于:https://www.cnblogs.com/huangfuyuan/p/9134544.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:使用 JavaScript 编写的杀死幽灵游戏(附源代码) 杀死鬼魂游戏是使用 Vanilla JavaScript、CSS 和 HTML 画布开发的简单项目。这款游戏很有趣。玩家必须触摸/杀死游荡的鬼魂才能得分。您必须将鼠标悬停在鬼魂上 - 尽量得分。鬼魂在眨眼间不断从一个地方移动到另一个地方。您必须在 1 分钟内尽可能多地杀死鬼魂。 游戏制作 这个游戏项目只是用 HTML 画布、CSS 和 JavaScript 编写的。说到这个游戏的特点,用户必须触摸/杀死游荡的幽灵才能得分。游戏会根据你杀死的幽灵数量来记录你的总分。你必须将鼠标悬停在幽灵上——尽量得分。你必须在 1 分钟内尽可能多地杀死幽灵。游戏还会显示最高排名分数,如果你成功击败它,该分数会在游戏结束屏幕上更新。 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox。要玩游戏,首先,单击 index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
javascript 中的 Paint War Game 是使用 HTML、CSS 和 JavaScript 开发的。谈到游戏玩法,这款游戏的主要目标是建造比敌人更多的油漆砖。您所要做的就是使用 WASD 键输入玩家的动作。您可以使用 VS Code 来运行该项目。 关于项目 每次您的玩家走过一块瓷砖时,它都会被涂成您的团队颜色。您必须在同一块瓷砖上走 4 次才能获得更多游戏点数。瓷砖会被您的团队挡住,并且不能再被偷走。如果您走过另一支球队的瓷砖,它会像您第一次走过时一样被涂上颜色。如果您创建一个封闭的被阻挡瓷砖图形,图形内所有未被阻挡的瓷砖都将固定为您的团队颜色。这个游戏充满乐趣,创造和重新即兴发挥会更有趣。 要运行此项目,我们建议您使用现代浏览器,例如 Google Chrome、  Mozilla Firefox。该游戏可能还支持 Explorer/Microsoft Edge。 演示: javascript 中的 Paint War Game 是使用 HTML、CSS 和 JavaScript 开发的。谈到游戏玩法,这款游戏的主要目标是建造比敌人更多的油漆砖。您所要做的就是使用 WASD 键输入玩家的动作。您可以使用 VS Code 来运行该项目。 关于项目 每次您的玩家走过一块瓷砖时,它都会被涂成您的团队颜色。您必须在同一块瓷砖上走 4 次才能获得更多游戏点数。瓷砖会被您的团队挡住,并且不能再被偷走。如果您走过另一支球队的瓷砖,它会像您第一次走过时一样被涂上颜色。如果您创建一个封闭的被阻挡瓷砖图形,图形内所有未被阻挡的瓷砖都将固定为您的团队颜色。这个游戏充满乐趣,创造和重新即兴发挥会更有趣。 要运行此项目,我们建议您使用现代浏览器,例如 Google Chrome、  Mozilla Firefox。该游戏可能还支持 Explorer/Microsoft Edge。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值