Как сделать шлагбаум по мастер-программе? - PullRequest
0 голосов
/ 22 апреля 2020

В настоящее время я хочу построить простую систему синхронизации, основанную на многих рабочих потоках + главный поток, который управляет другими и должен когда-нибудь синхронизировать их.

Мое ограничение:

  • Оставайтесь в стандартный c ++ (или экспериментальный), поэтому можно использовать std :: барьер и новую систему c ++ 20.

Здесь мой модульный тест:

int main()
{
    const Barrier::NumberThread nbThreads = 60;
    Barrier barrier;

    barrier.initialize(nbThreads);

    bool needSync = false;
    bool compute  = true;

    std::vector<bool> isSyncs;
    isSyncs.resize(nbThreads);
    std::vector<std::unique_ptr<std::thread>> threads;
    threads.resize(nbThreads);

    // Build threads
    auto itSync = isSyncs.begin();
    for (std::unique_ptr<std::thread>& thread : threads)
    {
        *itSync = false;

        thread = std::make_unique<std::thread>([&, itSync]()
            {
                while (compute)
                {
                    if (needSync)
                    {
                        *itSync = true;
                        // Wait here until master wake up threads
                        barrier.synchronizeThread();
                        *itSync = false;
                    }
                    else
                    {
                        // Normal working
                    }
                }                
            }
        );
        ++itSync;
    }

    // Check initial state
    for (const bool threadSync : isSyncs)
    {
        assert(!threadSync);
    }

    // Sync all
    needSync = true;
    barrier.masterWait();

    for(const bool threadSync : isSyncs)
    {
        assert(threadSync);
    }

    // Now all is sync
    needSync = false;
    barrier.masterContinue();

    // Stop all threads
    compute = false;
    for (auto& thread : threads)
    {
        thread->join();
    }

    barrier.release();

    // Now guaranty: result is stable
    for (const bool threadSync : isSyncs)
    {
        assert(!threadSync);
    }

    return 0;
}

Моя первая попытка можно найти здесь (но синхронизация не работает): https://ideone.com/xJLHbK

Спасибо!

...