#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
начинает ожидать завершения потока, но в этом случае фоновый поток никогда не завершается, потому что он содержит бесконечный цикл.