Я предполагаю, что Evil
- это Fun
в вашем примере.Теперь код, который я собираюсь написать, не является хорошим современным кодом (хотя я использую C ++ 11, см. constexpr
), но я надеюсь, что этого достаточно, чтобы показать вам проблему.string
s должны сохраняться до конца программы (или, по крайней мере, до тех пор, пока все потоки не будут выполнены):
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 предложил более простую реализацию, и я обновил ответ.