Visual C++ 如何使用线程启动非 void 函数

Posted

技术标签:

【中文标题】Visual C++ 如何使用线程启动非 void 函数【英文标题】:Visual C++ How to launch non void function with thread 【发布时间】:2013-05-15 16:17:23 【问题描述】:

我想问如何使用非 void 函数作为函数来运行线程。

我的意思是,像这样的函数:

void example(Mat& in, Mat& out)

如何将此函数用于beginthreadx 的线程?

将我要转换的代码粘贴到多线程代码中:

#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <stdio.h>
#include <windows.h>
#include <process.h>

using namespace std;
using namespace cv;

//filling array
void acquisisci (Mat in[])
in[0]=imread("C:/OPENCV/Test/imgtest/bird1.jpg",1);
in[1]=imread("C:/OPENCV/Test/imgtest/bird2.jpg",1);
in[2]=imread("C:/OPENCV/Test/imgtest/bird3.jpg",1);
in[3]=imread("C:/OPENCV/Test/imgtest/pig1.jpg",1);
in[4]=imread("C:/OPENCV/Test/imgtest/pig2.jpg",1);
in[5]=imread("C:/OPENCV/Test/imgtest/pig3.jpg",1);
   

//grey function
void elabora (Mat& in, Mat& out)
    if (in.channels()==3)
        cvtColor(in,out,CV_BGR2GRAY); //passa al grigio
        
  
  //threshold function
  void sogliata(Mat& in, Mat& out)
threshold(in,out,128,255,THRESH_BINARY);//fa la soglia
 

 //view
  void view (Mat& o)
imshow("Immagine",o);
   waitKey(600);
   

  int main()

Mat in[6],ou[6],out[6];

acquisisci(in); 

for (int i=0;i<=5;i++)
elabora(in[i],ou[i]); 


for (int i=0;i<=5;i++)
sogliata(ou[i],out[i]);
   

for (int i=0;i<=5;i++)
view(out[i]); 

  return 0;

  

我可以用并行线程做到这一点吗??

【问题讨论】:

【参考方案1】:

_beginthreadex 需要线程函数的特定签名。

 void(*thread_func)(void *);

要使用具有不同签名的函数,您通常只需创建一个“thunk”——一个除了调用您真正想要调用的函数之外什么都不做的小函数:

struct params 
    Mat &in;
    Mat &out;        
;

void thread_func(void *input)  
    params *p = (params *)input;

    example(input->in, input->out);

您可能还需要包含类似 Windows Event 的内容,以在输出中的数据准备就绪时发出信号——您不想在线程中的函数有机会之前尝试读取它写入数据:

struct params 
    Mat &in;
    Mat &out;        
    HANDLE event;

    params() : event(CreateEvent(NULL, 0, 0, NULL)) 
    ~params()  CloseHandle(event); 
;

void thread_func(void *input)  
    params *p = (params *)input;

    example(input->in, input->out);
    SetEvent(input->event);

然后调用函数以thread_func开始,当它需要结果时,在事件句柄上做WaitForSingleObjectWaitForMultipleObjects之类的操作,这样当它有需要的数据时就可以继续处理。

【讨论】:

很好的解释...清楚...我今晚试一试...谢谢!我必须在我的程序中执行多线程...4 个带有 openCV 参数的函数...【参考方案2】:

beginthreadx 只能与具有单个 void* 参数的函数一起使用。如果您需要多个参数,请创建一个包含两个值的结构,然后将指向该结构的指针作为唯一属性传递。例如:

struct Args 
  Mat& in;
  Mat& out;
;

void example(void* param) 
  Args* args = (Args*) param;
  process(args->in, args->out);

【讨论】:

我会避免使用引用成员创建结构或类,这会导致不相关的怪癖,这可能会令人困惑。 感谢您的回答和时间..那么,我必须使用什么?这是一个带有 openCV mat 参数的函数.. 你应该使用Mat* struct items。如果您的函数需要引用作为参数,您可以使用 * 运算符将指针转换为引用:process(*(args-&gt;in), *(args-&gt;out);【参考方案3】:

如果您使用的是 C++11,则可以使用 lambda 和 std::thread

Mat in, out;
std::thread([&] example(in, out); );

如果你没有使用 C++11,那么请忽略这个答案。

【讨论】:

以上是关于Visual C++ 如何使用线程启动非 void 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C++ 非托管库在 Visual Studio 2017 中为 Xamarin.Forms 设置项目?

C++ Visual Studio 非标准语法使用 '&' 创建指向成员的指针

如何在 Visual C++ 2010 中同步线程

如何开始使用 Visual C++ 编写 DLL?

std::thread,在线程中抛出异常会导致 Visual C++ 中的中止错误

如何在 Visual Studio 2019 C++ 中创建非虚拟文件夹