gpt4 book ai didi

c++ - 具有多线程成员函数的类

转载 作者:太空宇宙 更新时间:2023-11-04 12:20:49 25 4
gpt4 key购买 nike

我有一个类,我试图将它的一些成员函数转换为在不同的线程中运行。虽然程序没有问题,但是当它试图从图像缓冲区(由不同的线程更新)读取时它崩溃了。似乎问题是由在 _beginthread 中错误传递参数引起的。

下面的代码片段应该可以更清楚地解释我正在尝试做什么。基本上我想要完成的是让成员函数“fillBuffer”填充图像缓冲区,而程序的其余部分正在做其他事情,包括同时读取相同的图像缓冲区。

非常感谢任何有关语法的帮助。

 const int MaxImgBufferSize = 5;
class MyFrame : public wxFrame
{
public:
// constructors
MyFrame(const wxString& title);

private:
static vector <IplImage*> ImgBuffer;
void changeWP(wxCommandEvent&);
void fillBuffer();
void fillBufferFun();
static void __cdecl getImgFromBuffer(void *);
static void __cdecl pushImgBuffer(void *);
};

vector<IplImage*> MyFrame::ImgBuffer;

enter code here

MyFrame::MyFrame(const wxString& title)
: wxFrame(...)
{
// some stuff here
InitializeCriticalSection(&Section);
fillBuffer();

// some code here calls changeWP(wxCommandEvent&) from time to time
}

void MyFrame::fillBuffer()
{
while(ImgBuffer.size() <= MaxImgBufferSize)
{
fillBufferFun();
}
}

void MyFrame::fillBufferFun()
{
ImgBuffer* img;
// do something with img
_beginthread(pushImgBuffer, 0, img);
}

void MyFrame::pushImgBuffer(void *p)
{
EnterCriticalSection(&Section);
ImgBuffer.push_back( (IplImage*) p );
LeaveCriticalSection(&Section);
}

static unsigned int __stdcall getImgFromBuffer(void *);

void MyFrame::changeWP(wxCommandEvent&)
{
// do someting

IplImage* img = NULL;// new IplImage;
_beginthreadex( NULL, 0, MyFrame::getImgFromBuffer, img, 0, NULL );

// do something with img
fillBuffer();
}

unsigned int MyFrame::getImgFromBuffer(void *p)
{
EnterCriticalSection(&Section);
p = (void *)ImgBuffer[0];
ImgBuffer.erase(ImgBuffer.begin());
LeaveCriticalSection(&Section);
return 0;
}

最佳答案

这里有几个问题:

  1. 您的代码正在崩溃,因为您的 getImgFromBuffer 函数没有达到您想要的效果。从查看 getImgFromBuffer 的主体来看,您似乎正在尝试从 vector (MyFrame::ImgBuffer) 中复制一个指针值,并使用它覆盖从调用它的函数传入的指针值(即“img"MyFrame::changeWP 中的变量)。我说“似乎”是因为您在调用 getImgFromBuffer 之前在 MyFrame::changeWP (IplImage* img = new IplImage) 中初始化了“img”变量——为什么在分配另一个不同的对象之前将新对象分配给指针指向它的指针值(当然会导致内存泄漏)?无论如何,该赋值目前只是覆盖了 getImgFromBuffer 函数中的“p”参数的值,该值是按值传递的,并且在函数退出时将丢失。如果您希望 getImgFromBuffer 覆盖从其调用者传入的指针变量,则需要将指针传递给指针变量,如下所示:
void MyFrame::changeWP(wxCommandEvent&)
{
IplImage* img = NULL; // No memory leak, this time.
_beginthread(MyFrame::getImgFromBuffer, 0, & img);
//...
}

void MyFrame::getImgFromBuffer(void ** p)
{
//...
*p = (void *)ImgBuffer[0];
//...
}
  1. 我不明白“部分”是如何定义的,但无论它是静态的还是实例的,至少都是不好的形式。如果它是静态的,那么你就犯了每次构造时都重新初始化它的错误。我意识到这是一个代表顶级窗口的类,因此您可能不会制作其中的多个,但它仍然是一种糟糕的形式。如果 Section 是一个实例变量,那么您可能有多个 Section 对象试图保护单个(静态)资源,它们之间没有互斥。同样,只有一个窗口,所以这可能不是您的实际问题,但仍然...

可能还有更多,但这足以开始。

关于c++ - 具有多线程成员函数的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5201320/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com