多线程在发布配置中不起作用

问题描述 投票:0回答:1

我有一个程序可以在循环内计算一些复杂的数学内容。我将其简化为以下内容:

#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

c++ multithreading visual-studio configuration
1个回答
0
投票

该片段对我有用。使用 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();
}
© www.soinside.com 2019 - 2024. All rights reserved.