线程池的陷阱

Posted leijiangtao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池的陷阱相关的知识,希望对你有一定的参考价值。

线程池的陷阱

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

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

解决办法是:

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

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

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

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解决。

以上是关于线程池的陷阱的主要内容,如果未能解决你的问题,请参考以下文章

newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段

线程池的execute方法和submit方法有什么区别?

Java——线程池

Java线程池详解

Java线程池详解

Java 线程池详解