Программа с отдельным потоком уничтожается

#c

#c

Вопрос:

После объявления объекта в моем основном и запуска его функции в отдельном потоке моя программа завершает работу.

Я прочитал другой вопрос по SO, но из-за моего недостатка знаний в многопоточности я не могу понять, в чем моя конкретная проблема.

Вот мой класс под названием UART (без заголовочных файлов и показывающий только требуемое объявление cpp):

 void UART::run()
    {
        while(true)
        {
            _letter = _serial.read();
            if (_letter == "!")
            {
                _line = _serial.readline();
                _words.clear();
                std::istringstream f(_line);
                std::string s;
                //std::cout << _letter << std::endl;
                while (getline(f,s,'t'))
                {
                    _words.push_back(s);
                }
                this->fillVars();
            }
        }
    }

    void UART::fillVars()
    {
        if (_words[0] == "s")
        {
            _effort[0] = std::stoi(_words[1]);
            _effort[1] = std::stoi(_words[2]);
        }
        else if (_words[0] == "e")
        {
            this->convertToMeters();
        }

    }

    void UART::convertToMeters()
    {
        std::cout << _position[0];
        _position[0] = std::stod(_words[1]); // / _tick_meters;
        _position[1] = std::stod(_words[2]) / _tick_meters;
    }


    double UART::getPosition(std::string wheel)
    {
        if (wheel == "LEFT") return _position[0];
        else return _position[1];
    }
  

И мой основной cpp выглядит так:

 int main(int argc, char** argv)
{
    ros::init(argc, argv, "joint_node");
    std::string port("/dev/ttyACM0");

    unsigned long baud = 115200;

    try
    {
        serial::Serial my_serial(port, baud, serial::Timeout::simpleTimeout(1000));
        if(my_serial.isOpen()) ROS_INFO("Serial is %s", "open");

        genius::UART uart(my_serial, 380);
        std::thread uart_run(amp;genius::UART::run, uart);
        std::cout << uart.getPosition("LEFT") <<std::endl;

    } catch (std::exception amp;e)
    {
        std::cerr << "Unhandled Exception: " << e.what() << std::endl;

    }

    return 0;
}
  

Я понимаю, что после создания объекта uart я хочу запустить его функцию run() в отдельном потоке, поскольку я хочу, чтобы его значения обновлялись без прерывания в фоновом режиме. Поэтому всякий раз, когда я получаю доступ к его значениям, например, используя его функцию uart.getPosition("LEFT") , я получаю последние обновленные данные. Я думаю, мне не нужен .join() этот поток, поскольку я не хочу его ждать, поскольку он никогда не заканчивается.

Но по какой-то причине после вызова uart.getPosition("LEFT") моей программы происходит сбой, а также функция getPosition() никогда не выполняется, и я всегда получаю значение 0.

Комментарии:

1. Нет, .join() является обязательным. «это никогда не заканчивается» — это также должно быть исправлено. Никто не хочет иметь дело с какими-либо «бесконечными потоками». Также этот код страдает от состояния гонки.

2. @VTT Да, но я просто хочу, чтобы функция run() выполнялась в фоновом режиме до тех пор, пока ctrl-c не будет вызвана. Что касается состояния гонки, почему? Я не вижу, чтобы значения могли быть записаны каким-либо другим потоком.

3. Затем вам нужно будет реализовать обработчик Ctrl-C, который устанавливает exit флаг, который должен периодически проверяться в обоих потоках. Когда он установлен, основной поток должен вызываться .join , а фоновый поток должен завершаться. _position считывается из основного потока при вызове getPosition , в то время как фоновый поток записывает его при вызове convertToMeters

4. @VTT Хм, это имеет смысл, но я только что включил .join , и run() функция продолжала работать…

5. join начинает ожидать завершения потока, но в этом случае фоновый поток никогда не завершается, потому что он содержит бесконечный цикл.