- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有点困惑为什么 _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/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!