我有一个程序可以在循环内计算一些复杂的数学内容。我将其简化为以下内容:
#include <vector>
#include <thread>
#include <mutex>
struct Test
{
int threads = 4;
int threads_complete = 0;
bool idle = true;
bool stop = false;
std::mutex mtx;
// A single task
void task(int n)
{
bool done = false;
while (!stop)
{
if (idle || done) continue;
for (int i = 0; i <= 3 * (n + 1); i++)
{
printf("Task %d, iteration %d of %d\n", n, i, 3 * (n + 1));
std::this_thread::sleep_for(std::chrono::milliseconds(300));
}
done = true;
// Lock thread to increment the counter
mtx.lock();
threads_complete++;
mtx.unlock();
}
}
// Launch multiple tasks
void do_tasks()
{
std::vector<std::thread> v;
// Start multiple threads
for (int i = 0; i < threads; i++)
{
v.emplace_back(&Test::task, this, i);
}
// Launch subtasks in threads
idle = false;
// Wait for all tasks to finish
while (threads_complete != threads);
// Stop all the cycles inside tasks
stop = true;
// Await for threads to quit
for (auto& t : v)
{
t.join();
}
}
};
int main()
{
Test test;
test.do_tasks();
printf("\nDone\n");
getchar();
}
程序在调试中按预期工作,打印所有
Task ...
行和最后的 Done
。但是,当我在 Release 中运行它时,线程似乎被完全忽略,并且控制台中仅打印 Done
。
该片段对我有用。使用 std::condition_variable。
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <cstdio>
#include <chrono>
struct Test
{
int threads = 4;
int threads_complete = 0;
bool idle = true;
bool stop = false;
std::mutex mtx;
std::condition_variable condition;
// A single task
void task(int n)
{
bool done = false;
while (true)
{
{
std::unique_lock<std::mutex> lock(mtx);
if (stop) break;
}
if (idle || done) continue;
for (int i = 0; i <= 3 * (n + 1); i++)
{
printf("Task %d, iteration %d of %d\n", n, i, 3 * (n + 1));
std::this_thread::sleep_for(std::chrono::milliseconds(300));
}
done = true;
// Lock thread to increment the counter
{
std::lock_guard<std::mutex> lock(mtx);
threads_complete++;
if (threads_complete == threads)
{
condition.notify_one();
}
}
}
}
// Launch multiple tasks
void do_tasks()
{
std::vector<std::thread> v;
// Start multiple threads
for (int i = 0; i < threads; i++)
{
v.emplace_back(&Test::task, this, i);
}
// Launch subtasks in threads
{
std::lock_guard<std::mutex> lock(mtx);
idle = false;
}
// Wait for all tasks to finish
{
std::unique_lock<std::mutex> lock(mtx);
condition.wait(lock, [this] { return threads_complete == threads; });
}
// Stop all the cycles inside tasks
{
std::lock_guard<std::mutex> lock(mtx);
stop = true;
}
condition.notify_all();
// Await for threads to quit
for (auto& t : v)
{
t.join();
}
}
};
int main()
{
Test test;
test.do_tasks();
printf("\nDone\n");
getchar();
}