Error : An exception (first chance) at 0x76f6f9d2 in Boost_Mutex.exe: 0xC0000008: An invalid handle was specified
Error : An exception (first chance) at 0x76f6f9d2 in Boost_Mutex.exe: 0xC0000008: An invalid handle was specified
我写了一个程序来测试多线程。在 main
函数中创建了一个 thread t
。在function D
中,在thread t
中,将创建两个线程tt
和ttt
。函数 Process
在 thread ttt
中运行。在 Process
中将调用 class Dat
的成员函数 doAnotherThing
。在 thread tt
中将调用成员函数 doOneThing
。
当我调试这个程序时,出现错误: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.
谁能帮我解决这个问题并修改代码?
这些是我的代码:
"Dat.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
"Dat.cpp"
#include "Dat.h"
Dat::Dat()
{
}
Dat::~Dat()
{
}
void Dat::doOneThing()
{
x = 1;
}
void Dat::doAnotherThing()
{
omutex.lock();
x = 2;
omutex.unlock();
}
"main.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();
}
如果您对我的问题陈述有任何建议,请告诉我,我会修改它。谢谢
这里的主要问题是这一行:
boost::thread ttt(Process, (void*)&pParam);
你获取 pParam
的地址(它已经是一个指针),产生一个 void**
,然后将它转换回 void*
。 C++ 线程接口是类型安全的。你必须投出的事实是你做错事的有力标志。 (此外,您到处都使用 void*
。这是 C 线程接口所需要的,但对于 C++ 则不需要。)
无论如何,在 Process
中,您然后获取指向 pParam
的参数,并假装它指向您的 pPara
对象。 (为什么那个前缀是 p
呢?它不是指针!)然后你进入 pDat
指针,这当然是胡说八道,因为那里没有 Parameter
结构第一名。所以你得到的指针是无效的,并且没有指向有效的 Dat
结构,这意味着那里的 mutex
也无效,这意味着它的内部线程句柄是'无效,因此当您尝试锁定互斥量时,您终于得到了所需的崩溃。
以下是修复代码的方法:摆脱所有 void 指针并摆脱所有强制转换。此外,这不是绝对必要的,您还应该摆脱变量前缀。冗余的命名约定已经够糟糕了,但错误地应用冗余的命名约定将是一场灾难。
您还有一个错误:您没有使用互斥体保护 所有 您对 x
的访问,只有一个。这是没用的。你仍然有比赛条件。您必须保护对共享变量的所有访问。此外,您应该使用 lock_guard
RAII 对象而不是手动调用 lock
和 unlock
,这样您就永远不会忘记解锁。
我写了一个程序来测试多线程。在 main
函数中创建了一个 thread t
。在function D
中,在thread t
中,将创建两个线程tt
和ttt
。函数 Process
在 thread ttt
中运行。在 Process
中将调用 class Dat
的成员函数 doAnotherThing
。在 thread tt
中将调用成员函数 doOneThing
。
当我调试这个程序时,出现错误: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.
谁能帮我解决这个问题并修改代码?
这些是我的代码:
"Dat.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
"Dat.cpp"
#include "Dat.h"
Dat::Dat()
{
}
Dat::~Dat()
{
}
void Dat::doOneThing()
{
x = 1;
}
void Dat::doAnotherThing()
{
omutex.lock();
x = 2;
omutex.unlock();
}
"main.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();
}
如果您对我的问题陈述有任何建议,请告诉我,我会修改它。谢谢
这里的主要问题是这一行:
boost::thread ttt(Process, (void*)&pParam);
你获取 pParam
的地址(它已经是一个指针),产生一个 void**
,然后将它转换回 void*
。 C++ 线程接口是类型安全的。你必须投出的事实是你做错事的有力标志。 (此外,您到处都使用 void*
。这是 C 线程接口所需要的,但对于 C++ 则不需要。)
无论如何,在 Process
中,您然后获取指向 pParam
的参数,并假装它指向您的 pPara
对象。 (为什么那个前缀是 p
呢?它不是指针!)然后你进入 pDat
指针,这当然是胡说八道,因为那里没有 Parameter
结构第一名。所以你得到的指针是无效的,并且没有指向有效的 Dat
结构,这意味着那里的 mutex
也无效,这意味着它的内部线程句柄是'无效,因此当您尝试锁定互斥量时,您终于得到了所需的崩溃。
以下是修复代码的方法:摆脱所有 void 指针并摆脱所有强制转换。此外,这不是绝对必要的,您还应该摆脱变量前缀。冗余的命名约定已经够糟糕了,但错误地应用冗余的命名约定将是一场灾难。
您还有一个错误:您没有使用互斥体保护 所有 您对 x
的访问,只有一个。这是没用的。你仍然有比赛条件。您必须保护对共享变量的所有访问。此外,您应该使用 lock_guard
RAII 对象而不是手动调用 lock
和 unlock
,这样您就永远不会忘记解锁。