gpt4 book ai didi

C++ - _beginthreadex() 不启动线程

转载 作者:太空狗 更新时间:2023-10-29 21:17:33 25 4
gpt4 key购买 nike

我有点困惑为什么 _beginthreadex() 没有启动我的线程。基本上,我有一个线程:

编辑 #3 -- 添加了 while() 作为我代码的一部分,但我最初从未声明过,因此该线程必须始终运行,直到在内部提示退出代码它。而且它必须与我的实际应用程序一起运行(因此,我实际上不能 WaitForSingleObject(HANDLE, INFINITE))

unsigned int WINAPI MyThread1(LPVOID)
{
MessageBoxA(0, "We're in!", 0, 0);
while (TRUE)
{
// do something
}
}

我有我的 _beginthreadex() 代码:

/*
take note that, this is inside another function, and that function is also
called through a seperate _beginthreadex() call, so basically, this thread
is supposed to be called from within another thread
*/
if (user.settingsPage.ChangeVolume > 0)
{
_beginthreadex(0, 0, &MyThread1, 0, 0, 0);
// do some cleanup here, of non-related things
}

这个文件是一个 DLL 扩展。

为什么线程永远不会运行,换句话说,当 _beginthreadex() 时,为什么我从来没有看到 MessageBoxA() 出现在我的屏幕上通过?是不是不能在 DLL 文件中使用 _beginthreadex() 还是什么?

编辑#1

我已经实现了 Richard Chambers 在他的回复中所说的内容。

我从GetExitCodeThread()得到了错误码,并在MessageBoxA()中输出,错误码输出为259

查看 MSDN 系统错误代码列表后:here

错误码对应如下:

ERROR_NO_MORE_ITEMS
259 (0x103)
No more data is available.

编辑#2

我正在阅读 here ,并且我注意到此文本 如果线程返回 STILL_ACTIVE (259) 作为错误代码,测试此值的应用程序可以将其解释为表示线程仍在运行并在之后继续测试线程是否完成线程已终止,这可能会使应用程序陷入无限循环。 -- 这与我的问题有什么关系吗?如果是这样,线程仍在运行 是什么意思?如果它已经在运行,那么为什么我在 MessageBox 中看不到它的任何输出或它的其余内容?

那么,有了这些结论,我该怎么办?我该如何解决这个问题?

最佳答案

下面是两个在 Visual Studio 2012 中作为控制台应用程序编译和运行的简单示例。创建一个简单的 Windows 控制台应用程序,然后将此源代码粘贴到该文件中。错误检测方式不多,但主要部分有效。

_beginthreadex() 为 Windows API 中的 CreateThread() 提供了一个包装器,但是文档表明它为 C/C++ 运行时执行必要的启 Action 为一部分启动线程。参见 Windows threading: _beginthread vs _beginthreadex vs CreateThread C++详细了解这三种在 Windows 中启动线程的方式之间的区别。

在 DLL 和 COM 对象中一直使用启动线程,所以还有其他错误。以下示例一次启动一个线程。

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

#include "stdafx.h"

// necessary include files for a Console application wanting to do some Windows things with threads.
// ordinarily #include <Windows.h> would be added to stdafx.h for this Console application.
// Windows.h provides things such as the Sleep() function as well as definitions for HANDLE, etc.
// process.h provides the prototypes and declarations for _beginthreadex()
// iostream with no .h provides the C++ Standard Library I/O routines for std::cout
#include <Windows.h>
#include <process.h>

#include <iostream>

// list of arguments to provide to the thread being started up.
struct argList {
int i1;
int i2;
int i3;
};

unsigned int WINAPI myThread (void * args)
{
argList *pArgs = (argList *)args; // convert the LPVOID to the proper type to access the arguments.

// a bit of output to let us know we got here then a sleep to slow things down a touch.
std::cout << "myThread is running? args " << pArgs->i1 << ", " << pArgs->i2 << ", " << pArgs->i3 << std::endl;

Sleep(1000);

// add the arguments and return the sum.
return (pArgs->i1 + pArgs->i2 + pArgs->i3);
}

// declare the function in the DLL we are going to call.
__declspec(dllimport) HANDLE __cdecl Function1(void);

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread;
DWORD exitCode;
argList myArgs = {1, 2, 3};

std::cout << "main is running?" << std::endl;

// start a thread with the arguments we want to sum and wait for it to complete and return to us.
// when it returns we will fetch the return value which is the sum of the arguments.

hThread = (HANDLE)_beginthreadex (0, 0, myThread, &myArgs, 0, 0);
WaitForSingleObject (hThread, INFINITE); // Wait for the thread we started to complete, a kind of Join
GetExitCodeThread (hThread, &exitCode); // Get the thread's exit code so that we can print it out
CloseHandle (hThread); // We be done with the thread so close out it's handle to release resources

std::cout << "main ending, thread exit code " << exitCode << std::endl;

// now call the function in our DLL which will start up a thread there
// get its handle so that we can check the exit code, etc.
hThread = Function1();
WaitForSingleObject (hThread, INFINITE); // Wait for the thread we started to complete, a kind of Join
GetExitCodeThread (hThread, &exitCode); // Get the thread's exit code so that we can print it out
CloseHandle (hThread); // We be done with the thread so close out it's handle to release resources
std::cout << "main ending, Function1 exit code " << exitCode << std::endl;
return 0;
}

已使用标准添加向导将一个简单的控制台 DLL 项目添加到 Visual Studio 2012 解决方案中。我修改了一个空文件,而不是包含附加 DLL 消息处理程序等的 DLL 主文件。修改后的文件包含以下内容:

#include "stdafx.h"

#include <Windows.h>

#include <process.h>
#include <iostream>

unsigned int WINAPI myThread2 (void * args)
{

// a bit of output to let us know we got here then a sleep to slow things down a touch.
std::cout << "myThread2 is running? args " << std::endl;

MessageBox (0, L"A message2 text", L"Caption 2", 0);
Sleep(1000);

// add the arguments and return the sum.
return 345;
}

__declspec(dllexport) HANDLE __cdecl Function1(void)
{
std::cout << " in DLL, starting thread." << std::endl;

HANDLE hThread = (HANDLE)_beginthreadex (0, 0, myThread2, 0, 0, 0);

return hThread;
}

多线程

如果简单的应用程序被修改为在输出线程中有循环,我们可以同时运行多个线程。 main 可以修改为如下所示,我们启动两个我们有兴趣管理的不同线程,然后等待两个线程完成,然后检查两个线程的退出状态,如下所示。第三个线程已启动,但我们既不获取它的句柄也不管理它。它运行很短的时间然后结束。

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThreads[2];
DWORD exitCode;
unsigned int threadId;
argList myArgs = {1, 2, 3};

std::cout << "main is running?" << std::endl;

// start a thread with the arguments we want to sum and wait for it to complete and return to us.
// when it returns we will fetch the return value which is the sum of the arguments.

hThreads[0] = (HANDLE)_beginthreadex (0, 0, myThread, &myArgs, 0, &threadId);
hThreads[1] = Function1();

WaitForMultipleObjects (2, hThreads, TRUE, INFINITE); // Wait for all threads we started to complete, a kind of Join
GetExitCodeThread (hThreads[0], &exitCode); // Get the thread's exit code so that we can print it out
std::cout << "main ending, thread 1 exit code " << exitCode << std::endl;
GetExitCodeThread (hThreads[1], &exitCode); // Get the thread's exit code so that we can print it out
std::cout << "main ending, thread 2 exit code " << exitCode << std::endl;
CloseHandle (hThreads[0]); // We be done with the thread so close out it's handle to release resources
CloseHandle (hThreads[1]); // We be done with the thread so close out it's handle to release resources
return 0;
}

三个线程中的每一个都有一个简单的循环,该循环计算最终值并向标准输出显示一条消息。 Sleep(1000) 为我们提供了一种降低一切速度的方法。所以每个线程都有一个循环,如下所示,它来自线程号 3。

MessageBox (0, L"A message 3  text", L"Caption 3", 0);

std::cout << " myThread 3 after MessageBox - start loop" << std::endl;

for (int i = 0; i < 10; i++) {
Sleep(1000);
std::cout << " myThread 3 is running step "<< i << std::endl;
}

std::cout << "myThread 3 end" << std::endl;

此示例的 DLL 源在导出的入口点 Function1() 中启动一个线程,在 Function1() 中启动的线程启动第三个线程。

#include "stdafx.h"

#include <Windows.h>

#include <process.h>
#include <iostream>

unsigned int WINAPI myThread3 (void * args)
{
// a bit of output to let us know we got here then a sleep to slow things down a touch.
std::cout << "myThread3 is running? args " << std::endl;

MessageBox (0, L"A message 3 text", L"Caption 3", 0);

std::cout << " myThread 3 after MessageBox - start loop" << std::endl;

for (int i = 0; i < 10; i++) {
Sleep(1000);
std::cout << " myThread 3 is running step "<< i << std::endl;
}

std::cout << "myThread 3 end" << std::endl;
return 2356;
}

unsigned int WINAPI myThread2 (void * args)
{

// a bit of output to let us know we got here then a sleep to slow things down a touch.
std::cout << "myThread2 is running? args " << std::endl;

MessageBox (0, L"A message 2 text", L"Caption 2", 0);

std::cout << " myThread 2 after MessageBox - start myThread3 then loop" << std::endl;

HANDLE hThread = (HANDLE)_beginthreadex (0, 0, myThread3, 0, 0, 0);

for (int i = 0; i < 10; i++) {
Sleep(1000);
std::cout << " myThread 2 is running "<< i << std::endl;
}

std::cout << "myThread 2 end" << std::endl;
// add the arguments and return the sum.
return 345;
}

__declspec(dllexport) HANDLE __cdecl Function1(void)
{
std::cout << " in DLL, starting myThread 2." << std::endl;

HANDLE hThread = (HANDLE)_beginthreadex (0, 0, myThread2, 0, 0, 0);

return hThread;
}

输出显示了所有正在运行的线程。请注意,在输出中,由线程 2 启动的线程 3 在线程 2 由于启动其循环的延迟而结束后继续运行。线程2和线程3都在DLL代码中,在main调用Function1()的DLL入口点时启动。

main is running?
in DLL, starting myThread 2.
myThread is running? args myThread2 is running? args 1, 2, 3

myThread after MessageBox - start loop
myThread is running i = 0
myThread is running i = 1
myThread 2 after MessageBox - start myThread3 then loop
myThread3 is running? args
myThread is running i = 2
myThread 2 is running 0
myThread is running i = 3
myThread 2 is running 1
myThread is running i = 4
myThread 3 after MessageBox - start loop
myThread 2 is running 2
myThread is running i = 5
myThread 3 is running step 0
myThread 2 is running 3
myThread is running i = 6
myThread 3 is running step 1
myThread 2 is running 4
myThread is running i = 7
myThread 3 is running step 2
myThread 2 is running 5
myThread is running i = 8
myThread 3 is running step 3
myThread 2 is running 6
myThread is running i = 9
myThread 3 is running step 4
myThread 2 is running 7
myThread is running i = 10
myThread 3 is running step 5
myThread 2 is running 8
myThread is running i = 11
myThread 3 is running step 6
myThread 2 is running 9
myThread 2 end
myThread is running i = 12
myThread 3 is running step 7
myThread is running i = 13
myThread 3 is running step 8
myThread is running i = 14
myThread 3 is running step 9
myThread 3 end
myThread is running i = 15
myThread is running i = 16
myThread is running i = 17
myThread is running i = 18
myThread is running i = 19
myThread end
main ending, thread 1 exit code 6
main ending, thread 2 exit code 345

关于C++ - _beginthreadex() 不启动线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32673772/

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