samedi 18 mars 2017

Make same thread with loop not get the same mutex again and again without sleep

I want to compute two things in two threads where each of them has an endless loop. Those two don't depend on each other.

Additionally I want some output on the terminal also in an endless loop (just start again each time the last output was calculated, not any step in between needed). Therefore I want some local copies of the global variables (two consecutive iterations of the first calculation and one value of the second calculation) all in a safe state.

The problem is now that I have to add some sleep to the two calculations to ever get some output from func1. I checked CPU usage and the sleep definitely lowers it. How can I work around this?

#include <thread>
#include <condition_variable>
#include <mutex>

int n(0);
bifu s(baf);
foobar t(blub);

std::condition_variable cond;
std::mutex m1;
std::mutex m2;

void func1() {
    while (true) {
        // Not needed due to wait unlocking the mutex
        //std::this_thread::sleep_for(std::chrono::nanoseconds(1));

        std::unique_lock<std::mutex> lck1(m1);
        cond.wait(lck1);
        int n1(n);
        bifu s1(s);
        cond.wait(lck1);
        int n2(n);
        bifu s2(s);
        lck1.unlock();

        std::unique_lock<std::mutex> lck2(m2);
        foobar ti(t);
        lck2.unlock();

        // calculate and print some output 
    }
}

void func2() {
    while (true) {
        // Why do I need this to make func1 ever proceed (ok, really seldom and random func1 got the mutex) and
        // how to work around this without sleep lowering time for computations?
        std::this_thread::sleep_for(std::chrono::nanoseconds(1));

        std::unique_lock<std::mutex> lck1(m1);

        n++;

        // do some stuff taking some time with s

        cond.notify_all();
    }
}

void func3() {
    while (true) {
        // Why do I need this to make func1 ever proceed (it got thhe mutex never ever) and
        // how to work around this without sleep lowering time for computations?
        std::this_thread::sleep_for(std::chrono::nanoseconds(1));

        std::unique_lock<std::mutex> lck2(m2);
        // do something taking some time with t
    }
}

int main() {

    std::thread t1(func1);
    std::thread t2(func2);
    std::thread t2(func3);

    t1.join();
    t2.join();
    t3.join();

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire