使用boost线程池(多线程使用opencv处理图片)

[+]

需求

很多时候,需要用到多线程,但是线程每一次的分配都需要消耗时间,同时线程也不是无限制的开启的(需要固定一个数量)。

如果我们既想要固定数量,又不想每次都new一个线程,我们这么做就能满足要求:

a、固定一个数量,表示最大可使用线程的个数,threadCount=8;

b、在程序开始的时候,直接new出来threadCount个线程,假如存放到thread[threadCount-1]中

c、遇到一个任务,从thread[threadCount-1]中取出来一个线程,设置他的任务为Task,并且让threadCount-1,让此线程start

d、线程中的任务结束后让,threadCount+1

线程池

上面的流程,其实就是一个线程池的原型,为了使用方便,使用了boost的一个开源工程,threadpool,下载地址为

http://threadpool.sourceforge.net/



也可以从这里直接下载

把源码下载下来,解压得到一个文件夹和hpp文件



拷贝到(或者直接解压到boost目录中)





在vs中配置使用

打开vs(使用比较低版本的vs2010,要求比较高,同时没有c11可以使用,在vs2015也同样通过了测试

 

如果还不会使用OpenCVboost,可以参考blog文:

编译并使用opencv3.2http://blog.csdn.net/zengraoli/article/details/70185803

编译并使用boost1.63http://blog.csdn.net/zengraoli/article/details/70187556

 

测试例子的功能是浏览一个文件夹里面的1到10张图片,对比用单线程显示一张图片,和用8个线程同时显示的耗时对比

代码如下:

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include "stdafx.h"  
  2. #include "stdio.h"  
  3. #include "iostream"  
  4. #include "vector"  
  5. #include "windows.h"  
  6. #include "boost/threadpool.hpp"  
  7. #include "opencv2/opencv.hpp"  
  8.   
  9. using namespace std;  
  10. using namespace boost::threadpool;  
  11. using namespace cv;  
  12.   
  13. #define THREAD_COUNT        8           // 进程池的进程最大个数  
  14. #define FILE_NAME_LENGTH    64          // 文件名的长度  
  15. #define WINDOWS_NAME_LENGTH 32          // 窗口名的长度  
  16. #define SLEEP_SECOND        1000        // 每一个进程结束任务退出时,需要等待的时长  
  17. #define WAIT_KEY_SECOND     100         // opencv显示的等待时间  
  18. #define PIC_FOLDER_PATH     "D:\\pic\\" // 表明显示图片所在的文件夹路径  
  19. #define PIC_BEGIN_NUM       1           // 文件夹下最小图片的下标(包含)  
  20. #define PIC_END_NUM         11          // 文件夹下最大图片的下标(不包含)  
  21.   
  22. #pragma comment(lib, "lib/opencv_core320d.lib")  
  23. #pragma comment(lib, "lib/opencv_highgui320d.lib")  
  24. #pragma comment(lib, "lib/opencv_imgcodecs320d.lib")  
  25.   
  26. // 每个线程的任务  
  27. void Task(IplImage *p_img)  
  28. {  
  29.     //  boost::mutex::scoped_lock lock(m_io_monitor) //每个线程使用全局互斥来保证每次只有一个线程执行  
  30.     char windows_name[WINDOWS_NAME_LENGTH];  
  31.     sprintf_s(windows_name, "%d", boost::this_thread::get_id());  
  32.     cvNamedWindow(windows_name, CV_WINDOW_AUTOSIZE);  
  33.     cvShowImage(windows_name, p_img);  
  34.   
  35.     cvWaitKey(WAIT_KEY_SECOND);  
  36.     cvReleaseImage(&p_img);//释放图片  
  37. //  cvDestroyAllWindows();//销毁窗口  
  38.     Sleep(SLEEP_SECOND);  
  39. }  
  40. // 给线程池中的每一个线程分配任务,schedule会先把全部的任务接下来,如果没有线程空闲,则自动等待;wait遇到还有线程没有结束任务,那么其会进行阻塞等待  
  41. void ExecuteWithThreadpool()  
  42. {  
  43.     //设置允许开启的线程数  
  44.     pool tp(THREAD_COUNT);  
  45.     // opencv读取文件夹下的所有图片  
  46.     char file_name[FILE_NAME_LENGTH];  
  47.     IplImage *p_img;  
  48.     vector<IplImage *> v;  
  49.     for (int index = PIC_BEGIN_NUM; index < PIC_END_NUM; index++)  
  50.     {  
  51.         sprintf_s(file_name, "%s%d.png", PIC_FOLDER_PATH, index);  
  52.         p_img = cvLoadImage(file_name, 1);  
  53.         v.push_back(p_img);  
  54.     }  
  55.   
  56.     vector<IplImage *>::iterator it;  
  57.   
  58.     int index = 0;  
  59.     for (it = v.begin(); it != v.end(); it++)  
  60.     {  
  61.         cout << *it << endl;  
  62.         // 传入线程中作为参数  
  63.         tp.schedule(boost::bind(Task, *it));  
  64.         cout << "===========" << index++ << "===========" << endl;  
  65.     }  
  66.     tp.wait();  
  67.   
  68.     cout << "end." << endl;  
  69. }  
  70.   
  71.   
  72. // 显示一张图片  
  73. void ShowImg(IplImage *p_img, int index)  
  74. {  
  75.     char windows_name[WINDOWS_NAME_LENGTH];  
  76.     sprintf_s(windows_name, "%d", index);  
  77.     cvNamedWindow(windows_name, CV_WINDOW_AUTOSIZE);  
  78.     cvShowImage(windows_name, p_img);  
  79.   
  80.     cvWaitKey(WAIT_KEY_SECOND);  
  81.     cvReleaseImage(&p_img);//释放图片  
  82.     cvDestroyAllWindows();//销毁窗口  
  83.     Sleep(SLEEP_SECOND);  
  84. }  
  85.   
  86. // 不使用多线程的程序段  
  87. void ExecuteWithNotThread()  
  88. {  
  89.     // opencv读取文件夹下的所有图片  
  90.     char file_name[FILE_NAME_LENGTH];  
  91.   
  92.     IplImage *p_img;  
  93.     vector<IplImage *> v;  
  94.     for (int index = 1; index < 11; index++)  
  95.     {  
  96.         sprintf_s(file_name, "D:\\pic\\%d.png", index);  
  97.         p_img = cvLoadImage(file_name, 1);  
  98.         v.push_back(p_img);  
  99.     }  
  100.   
  101.     vector<IplImage *>::iterator it;  
  102.     int index = 0;  
  103.     for (it = v.begin(); it != v.end(); it++)  
  104.     {  
  105.         cout << *it << endl;  
  106.         // 传入线程中作为参数  
  107.         ShowImg(*it, index);  
  108.         cout << "===========" << index++ << "===========" << endl;  
  109.     }  
  110.   
  111.     cout << "end." << endl;  
  112. }  
  113.   
  114. int main()  
  115. {  
  116.     double start, end;  
  117.     start = clock();  
  118.     ExecuteWithNotThread();  
  119.     end = clock();  
  120.     printf("ExecuteWithNotThread:%fs \n", (end - start)/1000);  
  121.   
  122.     start = clock();  
  123.     ExecuteWithThreadpool();  
  124.     end = clock();  
  125.     printf("ExecuteWithThreadpool:%fs \n", (end - start)/1000);  
  126.   
  127.     return 0;  
  128. }  

效果如下:


转自:http://blog.csdn.net/zengraoli/article/details/70187693

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值