zoukankan      html  css  js  c++  java
  • 线程池的陷阱

    使用线程池要小心,一不小心就会导致程序挂死。举例说明这种情况。

    线程池中有一个同步队列存放数据,多个线程取队列中的数据去处理,数据的类型可能有多个,所以每种数据类型对应一个处理函数,假设某种数据的处理函数会把线程阻死,这时就悲剧了,这个阻死会蔓延到线程池的所有线程,最后线程池中所有的线程都挂死了,程序也挂死了。因为线程池的线程是不停的切换去处理数据的,凡是遇到会挂死线程的数据时,线程会一个个死掉,直到所有的线程挂死。

    解决办法是:

    一、一个类型的数据一个线程或者多个类型的数据一个线程,这样某个类型的数据处理导致线程挂死,其它线程还能正常运行,不会导致程序挂死。

    二、线程池中加超时处理,超时处理就不会挂死线程。

    使用线程池一定要保证线程处理函数不会挂死,否则整个程序都会挂死了。线程池内部的线程函数需要加超时处理,一个简单的处理方法是通过一个临时线程去控制该函数是否超时。原来的处理逻辑

    while (m_running)        
    {

            Task task; m_queue.Take(task);
    if (task) { task() } } 改成带超时的处理逻辑 while (m_running) { Task task; m_queue.Take(task); if (task) { boost::thread thd(task); if(thd.timed_join(boost::posix_time::seconds(5)))
              {   cout
    <<"没有超时"<<endl;
              }
    else
              {
    cout<<"超时"<<endl;
                //要做超时处理,这时要释放导致超时的资源,比如关闭socket或者关闭数据库
                //通知应用层做相应的处理如CloseSocket(),CloseDB()
              } } }

     超时处理时要把导致线程函数挂死的资源释放,比如关闭socket或者关闭数据库,让挂死的线程能退出。

    注意:这里只是一个程序的容错保证,并不解决根本问题,解决根本问题还是要把导致线程卡死的函数的bug解决。

  • 相关阅读:
    Mysql配置文件模板
    shell命令记录
    SuSE Linux Enterprise Server
    安装jdk1.8
    云南-第一个应用节点-ssh登录-卡顿的问题
    Python重新安装pip
    Centos6.5修改镜像为国内的阿里云源
    supervisord.conf
    Pandas连接Mysql数据库
    Vim速查命令简版
  • 原文地址:https://www.cnblogs.com/qicosmos/p/3225099.html
Copyright © 2011-2022 走看看