Как заставить два потока по очереди выполнять соответствующие критические разделы после окончания одного потока - PullRequest
0 голосов
/ 14 апреля 2020

В современном C ++ с потоками STL я хочу, чтобы два рабочих потока выполняли свою работу по очереди. Только один может работать одновременно, и каждый может получить только один ход, прежде чем другой сделает ход. У меня эта часть работает. Дополнительным ограничением является то, что один поток должен продолжать по очереди после завершения другого потока. Но в моем коде оставшийся рабочий поток блокируется после завершения первого рабочего потока. Я не понимаю, почему, учитывая, что последним, что сделал первый работник, была разблокировка и уведомление условной переменной, которая должна была разбудить второго. Вот код:

{
    std::mutex mu;
    std::condition_variable cv;
    int turn = 0;

    auto thread_func = [&](int tid, int iters) {
        std::unique_lock<std::mutex> lk(mu);
        lk.unlock();

        for (int i = 0; i < iters; i++) {
            lk.lock();
            cv.wait(lk, [&] {return turn == tid; });

            printf("tid=%d turn=%d i=%d/%d\n", tid, turn, i, iters);
            fflush(stdout);

            turn = !turn;
            lk.unlock();
            cv.notify_all();
        }
    };

    auto th0 = std::thread(thread_func, 0, 20);
    auto th1 = std::thread(thread_func, 1, 25); // Does more iterations

    printf("Made the threads.\n");
    fflush(stdout);

    th0.join();
    th1.join();

    printf("Both joined.\n");
    fflush(stdout);
}

Я не знаю, является ли это чем-то, что я не понимаю о параллелизме в потоках STL, или у меня просто ошибка логики c в моем коде. Обратите внимание, что есть вопрос о SO, который похож на этот, но без необходимости работать второму рабочему дольше, чем первый. Я не могу найти это прямо сейчас, чтобы сослаться на это. Заранее спасибо за помощь.

1 Ответ

0 голосов
/ 14 апреля 2020

Когда один поток завершен, другой будет ожидать уведомления, которое никто не отправит. Когда остается только один поток, вам нужно либо прекратить использование условной переменной, либо сигнализировать об условной переменной другим способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...