本文介绍使用多线程对一张图像进行滤波器处理加速,滤波器可以根据自己的需要去写,这里就不放出来了。
项目中通常代码比较远古,需要使用WIN32的多线程方式,先介绍第一种方法:
方法一:WIN32
WINDOWSThread为多线程调用的方法
处理同一张图片的时候,可以认为每个线程处理一定高度的图像,本文中设置为8个线程数量,图像为1000*1000*1;那么每个线程处理高度为125。
m_ThreadImgStruct为传递的参数,传递多个参数时,可以自己设置一个结构体,这样就可以把多个参数传递出去,
unsigned __stdcall WINDOWSThread(void *threadParam)
{
ThreadImgStruct *m_ThreadInput = (ThreadImgStruct*)threadParam;
...
}
void WIN32Thread()
{
int nCounterThread = 8;//定义线程数量
unsigned char *pDSData = new unsigned char[cnImgW*cnImgH];
m_ThreadImgStruct.pImgDst = pDSData;
m_ThreadImgStruct.cnImgH = cnImgH;
m_ThreadImgStruct.cnImgW= cnImgW;
m_ThreadImgStruct.pImgSrc = pSrcImg;
m_ThreadImgStruct.nHeightThree = nHeightThree;
for (int i = 0; i < nCounterThread;i++)
{
m_ThreadImgStruct.nThreadn = i;
hThread[i] = (HANDLE)_beginthreadex(nullptr, 0, &WINDOWSThread, &m_ThreadImgStruct, 0, &dwThreadID);//
WaitForSingleObject(hThread[i], INFINITE);
}
//cv::Mat imagepDSDataWindows = cv::Mat(cnImgH, cnImgW, CV_8UC1, pDSData);
//cv::imwrite("./imgSave/imagepDSDataWindows.bmp", imagepDSDataWindows);
for (int i = 0; i<nCounterThread; i++)
{
CloseHandle(hThread[i]);
}
}
方法2:Thread
thread方法使用起来比较简单,thread后面直接在多线程调用函数的参数即可。
void ThreadTest()
{
int nThreadBlock =8;
int cnCutHeight = cnImgH / nThreadBlock;
list<thread> listThread;
for (int nThread = 0; nThread< nThreadBlock; nThread++)
listThread.emplace_back(thread(HolesFilterByThread, pSrcImg, pDSData, cnImgW, cnImgH, cnCutHeight, nThread));
for (auto& thTemp : listThread)
{
thTemp.join();
//thTemp.detach();
}
}
使用WIN32多线程运行时间:
29ms
使用 thread多线程运行时间
14ms
不使用线程单独运行时间:
25 ms
总结:
对比发现使用thread速度会快一点,可能是传递结构体的时候比较耗时间,总体来说,使用多线程会比不使用多线程节省时间,当然具体的时间是根据滤波器计算的次数算的。