您的位置:首页 > 运维架构

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

2017-05-12 15:12 483 查看
[+]


需求

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

如果我们既想要固定数量,又不想每次都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/



也可以从这里直接下载
http://download.csdn.net/detail/zengraoli/9815332

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



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






在vs中配置使用

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

 

如果还不会使用OpenCV和boost,可以参考blog文:

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

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

 

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

代码如下:

[cpp] view
plain copy

 print?





#include "stdafx.h"  

#include "stdio.h"  

#include "iostream"  

#include "vector"  

#include "windows.h"  

#include "boost/threadpool.hpp"  

#include "opencv2/opencv.hpp"  

  

using namespace std;  

using namespace boost::threadpool;  

using namespace cv;  

  

#define THREAD_COUNT        8           // 进程池的进程最大个数  

#define FILE_NAME_LENGTH    64          // 文件名的长度  

#define WINDOWS_NAME_LENGTH 32          // 窗口名的长度  

#define SLEEP_SECOND        1000        // 每一个进程结束任务退出时,需要等待的时长  

#define WAIT_KEY_SECOND     100         // opencv显示的等待时间  

#define PIC_FOLDER_PATH     "D:\\pic\\" // 表明显示图片所在的文件夹路径  

#define PIC_BEGIN_NUM       1           // 文件夹下最小图片的下标(包含)  

#define PIC_END_NUM         11          // 文件夹下最大图片的下标(不包含)  

  

#pragma comment(lib, "lib/opencv_core320d.lib")  

#pragma comment(lib, "lib/opencv_highgui320d.lib")  

#pragma comment(lib, "lib/opencv_imgcodecs320d.lib")  

  

// 每个线程的任务  

void Task(IplImage *p_img)  

{  

    //  boost::mutex::scoped_lock lock(m_io_monitor) //每个线程使用全局互斥来保证每次只有一个线程执行  

    char windows_name[WINDOWS_NAME_LENGTH];  

    sprintf_s(windows_name, "%d", boost::this_thread::get_id());  

    cvNamedWindow(windows_name, CV_WINDOW_AUTOSIZE);  

    cvShowImage(windows_name, p_img);  

  

    cvWaitKey(WAIT_KEY_SECOND);  

    cvReleaseImage(&p_img);//释放图片  

//  cvDestroyAllWindows();//销毁窗口  

    Sleep(SLEEP_SECOND);  

}  

// 给线程池中的每一个线程分配任务,schedule会先把全部的任务接下来,如果没有线程空闲,则自动等待;wait遇到还有线程没有结束任务,那么其会进行阻塞等待  

void ExecuteWithThreadpool()  

{  

    //设置允许开启的线程数  

    pool tp(THREAD_COUNT);  

    // opencv读取文件夹下的所有图片  

    char file_name[FILE_NAME_LENGTH];  

    IplImage *p_img;  

    vector<IplImage *> v;  

    for (int index = PIC_BEGIN_NUM; index < PIC_END_NUM; index++)  

    {  

        sprintf_s(file_name, "%s%d.png", PIC_FOLDER_PATH, index);  

        p_img = cvLoadImage(file_name, 1);  

        v.push_back(p_img);  

    }  

  

    vector<IplImage *>::iterator it;  

  

    int index = 0;  

    for (it = v.begin(); it != v.end(); it++)  

    {  

        cout << *it << endl;  

        // 传入线程中作为参数  

        tp.schedule(boost::bind(Task, *it));  

        cout << "===========" << index++ << "===========" << endl;  

    }  

    tp.wait();  

  

    cout << "end." << endl;  

}  

  

  

// 显示一张图片  

void ShowImg(IplImage *p_img, int index)  

{  

    char windows_name[WINDOWS_NAME_LENGTH];  

    sprintf_s(windows_name, "%d", index);  

    cvNamedWindow(windows_name, CV_WINDOW_AUTOSIZE);  

    cvShowImage(windows_name, p_img);  

  

    cvWaitKey(WAIT_KEY_SECOND);  

    cvReleaseImage(&p_img);//释放图片  

    cvDestroyAllWindows();//销毁窗口  

    Sleep(SLEEP_SECOND);  

}  

  

// 不使用多线程的程序段  

void ExecuteWithNotThread()  

{  

    // opencv读取文件夹下的所有图片  

    char file_name[FILE_NAME_LENGTH];  

  

    IplImage *p_img;  

    vector<IplImage *> v;  

    for (int index = 1; index < 11; index++)  

    {  

        sprintf_s(file_name, "D:\\pic\\%d.png", index);  

        p_img = cvLoadImage(file_name, 1);  

        v.push_back(p_img);  

    }  

  

    vector<IplImage *>::iterator it;  

    int index = 0;  

    for (it = v.begin(); it != v.end(); it++)  

    {  

        cout << *it << endl;  

        // 传入线程中作为参数  

        ShowImg(*it, index);  

        cout << "===========" << index++ << "===========" << endl;  

    }  

  

    cout << "end." << endl;  

}  

  

int main()  

{  

    double start, end;  

    start = clock();  

    ExecuteWithNotThread();  

    end = clock();  

    printf("ExecuteWithNotThread:%fs \n", (end - start)/1000);  

  

    start = clock();  

    ExecuteWithThreadpool();  

    end = clock();  

    printf("ExecuteWithThreadpool:%fs \n", (end - start)/1000);  

  

    return 0;  

}  

效果如下:



转自:http://blog.csdn.net/zengraoli/article/details/70187693
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐