我正在研究多线程。我将Win32Api用于CreateThread。 我有包含5个驱动器号的char数组。我需要MessageBox这些驱动器一个接一个。
这是我的代码:
DWORD WINAPI Fun(LPVOID param)
{
const char* str = (const char*)param;
MessageBox(NULL, str, "hello", MB_OK | MB_ICONQUESTION);
return 0;
}
void StartWork()
{
int n, d, b = 0;
char dd;
DWORD dr = GetLogicalDrives();
HANDLE threads[26];
for (int i = 0; i < 26; i++)
{
n = ((dr >> i) & 1);
if (n == 1)
{
dd = char(65 + i);
std::string text(1, dd);
d = GetDriveType((text + ":\\").c_str());
if (d == DRIVE_REMOVABLE || d == DRIVE_FIXED || d == DRIVE_REMOTE)
{
threads[b] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Evil, (LPVOID)text.c_str(), 0, NULL);
b += 1;
}
}
}
WaitForMultipleObjects(b, threads, TRUE, 1000);
}
输出不是我想要的。我只有最后一个磁盘字母(我有3个磁盘-C,D,E,输出是msgbox“ E”的3倍)
答案 0 :(得分:3)
在您的示例中,我假设Evil
是Fun
。现在,我要编写的代码不是很好的现代代码(尽管我正在使用C ++ 11,请参见constexpr
),但我希望它足以向您展示问题。 string
必须生存到程序结束(或至少直到所有线程完成):
void StartWork()
{
int n, d, b = 0;
char dd;
DWORD dr = GetLogicalDrives();
constexpr std::size_t numMaxThreads = 26;
HANDLE threads[numMaxThreads];
//Now the strings survive until the end of the program, #include <array>
std::array<std::string, numMaxThreads> texts;
for (int i = 0; i < numMaxThreads; i++)
{
n = ((dr >> i) & 1);
if (n == 1)
{
dd = char(65 + i);
std::string text(1, dd);
texts[b] = std::move(text);
d = GetDriveType((texts[b] + ":\\").c_str());
if (d == DRIVE_REMOVABLE || d == DRIVE_FIXED || d == DRIVE_REMOTE)
{
threads[b] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Fun, (LPVOID)texts[b].c_str(), 0, NULL);
b += 1;
}
}
}
WaitForMultipleObjects(b, threads, TRUE, 1000);
}
现在,这是好的现代代码吗?否,我建议您使用std::thread
:这样可以更好地处理string
的生命周期,例如
#include <string>
#include <vector>
#include <thread>
#include <Windows.h>
void Fun(const std::string& str)
{
MessageBox(NULL, str.c_str(), "hello", MB_OK | MB_ICONQUESTION);
}
void StartWork()
{
int n, d;
char dd;
DWORD dr = GetLogicalDrives();
std::vector<std::thread> threads;
for (int i = 0; i < 26; i++)
{
n = ((dr >> i) & 1);
if (n == 1)
{
dd = char(65 + i);
std::string text(1, dd);
d = GetDriveType((text + ":\\").c_str());
if (d == DRIVE_REMOVABLE || d == DRIVE_FIXED || d == DRIVE_REMOTE)
{
//thanks to zett42 for this simplification
threads.emplace_back(Fun, text);
}
}
}
//We could be using for_each also
for (auto& thread : threads) { thread.join(); }
}
请注意:
std::thread
可以避免内存管理的麻烦,将内存的所有权传递给线程,然后由线程负责清理编辑:zett42用户建议一个更简单的实现,我更新了答案。