0

我写了一个程序来测试多线程。在main函数thread t中创建了 a。in function D,即 in ,将创建thread t两个线程。该函数在. 在一个成员函数中会被调用。在一个成员函数中会被调用。tttttProcessthread tttProcessdoAnotherThingclass Datthread ttdoOneThing

当我调试这个程序时,出现了一个错误:An exception (first chance) at 0x76f6f9d2 in Boost_Mutex.exe: 0xC0000008: An invalid handle was specified.

有时会发生此错误而不是上面的错误:

Run-Time Check Failure #2 - Stack around the variable 'oDat' was corrupted.

谁能帮我解决这个问题并修改代码?

这些是我的代码:

“达.h”

#pragma once 

#ifndef DAT_H
#define DAT_H

#include <boost\thread\thread.hpp>
using namespace std;

class Dat 
{

public:
    Dat();
    ~Dat();
    void doOneThing();
    void doAnotherThing ();
private:
    boost::mutex omutex;

    int x;
};
#endif // DAT_H

“数据.cpp”

#include "Dat.h"

Dat::Dat()
{

}

Dat::~Dat()
{

}

void Dat::doOneThing()
{
    x = 1;  
}

void Dat::doAnotherThing()
{
    omutex.lock();
    x = 2;
    omutex.unlock();
}

“主.cpp”

#include "Dat.h"
#include <boost\function.hpp>

struct Parameter // the Parameters of function Process and D
{
 Dat* pDat;
};
void Process(void*pParam)
{
    // init the parameter 
    parameter* pUserParams = (parameter*)pParam;
    pUserParams->pDat->doAnotherThing();
}

void D(void* pParam)
{
    // init the parameter 
    parameter* pUserParams = (parameter*)pParam;
    boost::function<void()> f;
    boost::thread ttt(Process, (void*)&pParam);
    f = boost::bind(&Dat::doOneThing, pUserParams->pDat);   
    // the capture thread will be started
    boost::thread tt(f);

    ttt.join();
    tt.join();
}

void main()
{
    Dat oDat;
    parameter pPara ;
    pPara.pDat = &oDat;
    boost::thread t(D,(void*)&pPara);
    t.join();
}

如果您对我的问题陈述有任何建议,请告诉我,我会修改它。谢谢

4

1 回答 1

3

这里的主要问题是这一行:

boost::thread ttt(Process, (void*)&pParam);

您获取pParam(已经是指针)的地址,产生 a void**,然后将其转换回 a void*。C++ 线程接口是类型安全的。你必须施放的事实是一个强有力的指标,表明你做错了什么。(此外,您对void*所有地方的使用。这对于 C 线程接口是必需的,但对于 C++ 则不需要。)

无论如何,Process然后在你的参数中,它指向pParam,并假装它指向你的pPara对象。(为什么还要加上前缀p?它不是指针!)然后你进入pDat指针,这当然是无稽之谈,因为首先那里没有Parameter结构。所以你得到的指针是无效的,并且没有指向一个有效的Dat结构,这意味着那里的mutexin 也无效,这意味着它的内部线程句柄是无效的,所以你最终得到了你的崩溃当您尝试锁定互斥锁时需要。

以下是您修复代码的方法:摆​​脱所有 void 指针并摆脱所有强制转换。此外,这不是绝对必要的,您还应该摆脱变量前缀。冗余命名约定已经够糟糕了,但错误应用的冗余命名约定是一场灾难。

您还有一个错误:您没有使用互斥锁保护所有访问x,只有一个。这是没用的。你仍然有比赛条件。您必须保护对共享变量的所有访问。此外,您应该使用lock_guardRAII 对象而不是手动调用lockand unlock,这样您就永远不会忘记解锁。

于 2015-08-25T08:06:12.340 回答