gpt4 book ai didi

c++ - 线程没有运行,为什么?

转载 作者:行者123 更新时间:2023-11-28 04:43:59 25 4
gpt4 key购买 nike

我写了一个简单的测试应用程序来证明线程工作:

    // Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

class clsTest {
private:
uintptr_t muintHandle;

static unsigned int __stdcall fnThread(void* pData) {
while( 1 ) {
_sleep(1000);
printf("In fnThread, handle = %d\n", *(uintptr_t*)pData);
}
return 0;
}
public:
clsTest() {
muintHandle = _beginthreadex(0, 0, &clsTest::fnThread, (void*)&muintHandle, 0, 0);
printf("clsTest(), after beginthreadex, handle = %u\n", muintHandle);
}
};

int _tmain(int argc, _TCHAR* argv[]) {
clsTest* pT = NULL;

while(1) {
printf("From _tmain\n");

if ( pT == NULL ) {
pT = new clsTest();
}
_sleep(1000);
}
return 0;
}

这个应用程序的输出是:

    From _tmain
clsTest(), after beginthreadex, handle = 112
In fnThread, handle = 112
From _tmain
In fnThread, handle = 112
From _tmain
In fnThread, handle = 112
From _tmain
In fnThread, handle = 112
From _tmain
In fnThread, handle = 112
From _tmain
In fnThread, handle = 112
...

Continuously 这正是我希望看到的......现在在一个更大的项目中我有一个基类:

    typedef enum {
eIdle = 0, //Thread is not working at all
eStarted, //Thread has been started but is not fully operational yet
eRunning, //Thread is working normally
ePausing, //Thread is requested to enter the paused state
ePaused, //Thread is paused
eTerminating //Termination has been requested but not completed yet
} eThreadStates;

class clsOpenLDVthread {
protected:
volatile eThreadStates meState;
CRITICAL_SECTION mCritControl; // critical section for thread control
char mszName[80];
HANDLE mhEvent, mhThread;
virtual bool blnStart() = 0;

public:
clsOpenLDVthread(LPCSTR pszName);
~clsOpenLDVthread();

bool inline blnIsRunning();
bool inline blnIsStopped();
bool inline blnIsStopping();
bool inline blnIsStarting();
bool inline blnIsPausing();
bool inline blnIsPaused();
bool blnPause(bool blnState);
virtual bool blnStop();
};

clsOpenLDVthread::clsOpenLDVthread(LPCSTR pszName) : meState(eIdle)
, mhThread(NULL) {
::InitializeCriticalSection(&mCritControl); //Get a critical section
//Get a unique name for signaling event
sprintf(mszName, "%s%d", pszName, ::GetCurrentProcessId());
//Get the event object
mhEvent = ::CreateEvent(NULL, FALSE, FALSE, mszName);
}
clsOpenLDVthread::~clsOpenLDVthread() {
if ( blnIsPaused() ) {
blnPause(false);
}
if ( blnIsRunning() ) {
blnStop();
}
if ( mhEvent ) {
::CloseHandle(mhEvent);
mhEvent = NULL;
}
::DeleteCriticalSection(&mCritControl);
}
bool clsOpenLDVthread::blnIsPaused() {
return meState == ePaused;
}
bool clsOpenLDVthread::blnIsPausing() {
return meState == ePausing;
}
bool clsOpenLDVthread::blnIsRunning() {
return meState == eRunning;
}
bool clsOpenLDVthread::blnIsStarting() {
return meState == eStarted;
}
bool clsOpenLDVthread::blnIsStopped() {
return meState == eIdle;
}
bool clsOpenLDVthread::blnIsStopping() {
return meState == eTerminating;
}
bool clsOpenLDVthread::blnPause(bool blnState) {
bool blnResult = mhThread != NULL;
if ( blnResult ) {
if ( blnState ) {
unsigned uintCountDown = 10u;

if ( blnIsRunning() || blnIsPausing() ) {
meState = ePausing;
while( blnIsPausing() && -- uintCountDown ) {
::SetEvent(mhEvent);
//Give thread chance to run and pause
_sleep(751);
}
blnResult = blnIsPaused();
}
} else {
if ( blnIsPaused() ) {
meState = eRunning;
//this will need replacing...mhThread->ResumeThread();
}
blnResult = true;
}
}
return blnResult;
}
bool clsOpenLDVthread::blnStop() {
bool blnResult = meState == eIdle;
unsigned uintCountDown = 100u;

if ( blnIsPaused() ) {
blnPause(false);
}
if ( blnIsRunning() ) {
meState = eTerminating;

while( !blnIsStopped() && --uintCountDown ) {
if ( mhEvent ) {
::SetEvent(mhEvent);
}
//Give thread a change to run and terminate
_sleep(501);
}
blnResult = blnIsStopped();
mhThread = NULL;
}
return blnResult;
}

最后一个派生类,实现了线程类,提供了blnStart方法:

    class clsOpenLDVrdr : public clsOpenLDVthread {
public:
//Maximum size of uplink data per single transfer
static const unsigned mscuBuffersize;
private:
//The thread's main routine
static void msgReaderThread(LPVOID lpParam);

public:
clsOpenLDVrdr();
virtual ~clsOpenLDVrdr();
//Call this to start the thread, see clsOpenLDVthread for more operations
virtual bool blnStart();
};

const unsigned clsOpenLDVrdr::mscuBuffersize = MAX_OPENLDV_DATA;

clsOpenLDVrdr::clsOpenLDVrdr() : clsOpenLDVthread(_T("EvOpenLDVrdr")) {
}
clsOpenLDVrdr::~clsOpenLDVrdr() {
}
bool clsOpenLDVrdr::blnStart() {
bool blnResult = false;
if ( blnIsStopped() ) {
meState = eStarted;
//Create the thread
mhThread = (HANDLE)_beginthread(&clsOpenLDVrdr::msgReaderThread
,0, NULL);
blnResult = mhThread != NULL;

while( blnResult && (meState == eStarted) ) {
//Give the thread chance to start and initialize
_sleep(501);
}
}
return blnResult && (meState == eRunning);
}
void clsOpenLDVrdr::msgReaderThread(LPVOID lpParam) {
OutputDebugString("msgReaderThread\n");
}

创建了类 clsOpenLDVrdr 的实例并调用了 blnStart 方法:

    clsOpenLDVrdr* pobjReader = new clsOpenLDVrdr();
pobjReader->blnStart();

我可以在调试器中看到正在调用“blnStart”并进入其中,所有内容都已执行...但线程从未运行。

还尝试使用 _beginthreadex 而不是 _beginthread:

    mhThread = (HANDLE)_beginthreadex(0, 0, pfnThread, pobParam, 0, 0);

没有区别。这里存在某种不兼容问题,因为我在本文开头创建的简单示例有效,并且两个版本之间没有太大区别。除了它的使用方式……第一个简单示例是作为 Windows 控制台应用程序创建的。我遇到困难的项目是在 DLL 中。

我使用调试器附加到 DLL 并逐步执行代码,直到它在 beginthread 调用之后进入循环,然后它才会永远循环,永远不会进入线程。

我刚刚尝试了以下操作,添加了一个带有标准 C 函数的独立线程:

    unsigned __stdcall threadTest(void* pobjData) {
OutputDebugString("threadTest\n");
return 0;
}

然后我修改“_beginthread”调用如下:

    mhThread = (HANDLE)_beginthreadex(0, 0, threadTest, pobjParam, 0, 0);

遗憾的是结果是一样的,threadTest函数没有被调用。但是返回了一个有效的句柄。

找到这个:

unable to call a thread in dll file

看起来很有趣,可以解释我遇到的奇怪行为。

最佳答案

已解决...起初我没有意识到,但出于某种原因,现有的 DLL 调用了:

    DisableThreadLibraryCalls(hInstance);

这会阻止线程运行。将其注释掉后一切正常。

关于c++ - 线程没有运行,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49653102/

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