C++: не работает простейшая программа с использованием многопоточности (std::thread)

Рейтинг: 0Ответов: 2Опубликовано: 31.03.2023

Задание: На маршруте несколько остановок. На одной остановке может останавливаться несколько автобусов одновременно, но не более заданного числа. Необходимо с помощью многопоточности реализовать работу автобусов.

Я написал код, однако в процессе компиляции возникают две ошибки:

Ошибка  C2893   Сбой при специализации функции-шаблона "unknown-type std::invoke(_Callable &&) noexcept(<expr>)".
Ошибка  C2672   "invoke": не найдена соответствующая перегруженная функция

Код:

#include <iostream>
#include <stdlib.h>
#include <thread>
#include <Windows.h>

using namespace std;

class Bus {
private:
    int currentStop;
    int number;
public:
    Bus() {
        this->currentStop = this->number = 0;
    }
    int run(int stops) {
        cout << "\nТекущая остановка автобуса №" << this->number << ": " << this->currentStop;
        Sleep(300);
        this->currentStop = rand() % (stops - this->currentStop) + this->currentStop;
        return currentStop;
    }

    int getCurrentStop() {
        return currentStop;
    }

    void setCurrentStop(int currentStop) {
        this->currentStop = currentStop;
    }

    int getNumber() {
        return number;
    }

    void setNumber(int number) {
        this->number = number;
    }
    ~Bus() {

    }
};

int main() {
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    int amountOfStops, amountOfBuses, buses;
    cout << "Введите количество остановок: ";
    cin >> amountOfStops;
    cout << "Введите количество автобусов: ";
    cin >> buses;
    cout << "\nВведите количество автобусов на одной остановке: ";
    cin >> amountOfBuses;
    Bus* massiv = new Bus[buses];
    for (int i = 0; i < buses; i++) {
        thread th(massiv[i].run(amountOfStops));
    }
    return 0;
}

Что он должен делать? Создаётся массив объектов Bus, в котором у каждого элемента в потоке должен выполняться метод run(). Этот метод просто возвращает рандомный номер "текущей" остановки для данного автобуса, причём такой, что он всегда больше предыдущего номера этого автобуса.

Почему этот код не работает?

Ответы

▲ 2

По-хорошему, передавать надо параметры так:

thread th(&Bus::run,massiv[i],amountOfStops);

Вы же не хотите передавать просто int — результат вызова run объекта massiv[i]?

Только вот работать это не будет.
Потому что вы создаете объект thread, который сразу же и уничтожаете, а для уничтожения такого объекта destructs the thread object, underlying thread must be joined or detached. У вас же этого не наблюдается...

P.S. Решает ли ваш код поставленную задачу в принципе — не смотрел.

▲ 0

Нужно не вызывать функцию до конструктора, надо передать адрес на функцию, передать два параметра (this, и stops), ну и как подметил @Harry, нужно вызвать join:

#include <Windows.h>
#include <cstdlib>
#include <iostream>
#include <thread>

class Bus
{
private:
    int currentStop;
    int number;
public:
    Bus();
    ~Bus();
    int run(int);
    int getCurrentStop();
    void setCurrentStop(int);
    int getNumber();
    void setNumber(int);
};

Bus::Bus()
    : currentStop(0),
      number(0)
{
}

Bus::~Bus()
{
}

int Bus::run(int stops)
{
    std::cout << "\nТекущая остановка автобуса №" << this->number << ": " << this->currentStop;
    Sleep(300);
    this->currentStop = rand() % (stops - this->currentStop) + this->currentStop;
    return this->currentStop;
}

void Bus::setCurrentStop(int currentStop)
{
    this->currentStop = currentStop;
}

int Bus::getNumber()
{
    return this->number;
}

void Bus::setNumber(int number)
{
    this->number = number;
}

int main() {
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    int amountOfStops, amountOfBuses, busesCount;
    std::cout << "Введите количество остановок: ";
    std::cin >> amountOfStops;
    std::cout << "Введите количество автобусов: ";
    std::cin >> busesCount;
    std::cout << "\nВведите количество автобусов на одной остановке: ";
    std::cin >> amountOfBuses;
    Bus* buses = new Bus[busesCount];
    for (int i = 0; i < busesCount; i++) {
        std::thread(&Bus::run, buses[i], amountOfStops).join();
    }
    delete[] buses;
    return 0;
}