Упражнение многопоточности - PullRequest
0 голосов
/ 08 сентября 2018

Мне нужно решить это упражнение многопоточности. Я должен создать класс, в котором 5 потоков ожидают друг друга, а когда приходит пятый, все они разблокированы. Я хотел бы использовать мьютекс и переменную условия, но я не знаю, правильно ли я их использую. Я создаю класс с помощью метода add (), который увеличивает переменную X на 1, создает поток, который получает функцию print (), а затем присоединяет ее (). Функция print () проверяет, является ли переменная X младшей из пяти, если это так, что условная переменная ждет, иначе условная переменная пробуждает весь поток с помощью функции notify_all (). Компилятор выдает ошибку 0, но с отладкой я вижу, что программа заходит в тупик. Вот фрагмент

#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;

void print(mutex & mtx, condition_variable & convar, int x) {
    if (x < 5){
        unique_lock<mutex> lock(mtx); //acquire and lock the mutex
        convar.wait(lock); //unlock mutex and wait
    }
    else {
        convar.notify_all();
        cout << "asdasd" << endl;
    }
}

class foo {
public:
    void add() {
        this->x = x + 1;
        thread t1(print, ref(mtx), ref(cv), x);
        t1.join();
    }

private:
    mutex mtx;
    condition_variable cv;
    int x;
};

int main() {
    foo f;
    f.add();
    f.add();
    f.add();
    f.add();
    f.add();
}

1 Ответ

0 голосов
/ 08 сентября 2018

Ваша функция

void add() {
    this->x = x + 1;
    thread t1(print, ref(mtx), ref(cv), x);
    t1.join();
}

создает отдельный поток и затем ждет (join()), пока поток не закончится. Так как ваша функция потока

void print(mutex & mtx, condition_variable & convar, int x) {
    if (x < 5){
        unique_lock<mutex> lock(mtx);
        convar.wait(lock); // waits if x < 5
    }
    // ...

и x предположительно (вы не смогли его инициализировать) <5, у вас тупик. </p>

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <condition_variable>
using namespace std;

void print(mutex & mtx, condition_variable & convar, int x)
{
    if (x < 5) {
        unique_lock<mutex> lock{ mtx };
        convar.wait(lock);
    } else {
        convar.notify_all();
        cout << "asdasd\n";
    }
}

class foo {
private:
    mutex mtx;
    condition_variable cv;
    int x{ 0 };
    std::vector<thread> threads;
public:
    void add() {
        ++x;
        threads.push_back(thread(print, ref(mtx), ref(cv), x));
    }

    ~foo() {
        for (auto &t : threads)
            t.join();
    }
};

int main() {
    foo f;
    f.add();
    f.add();
    f.add();
    f.add();
    f.add();
}
...