Условия цикла записываются так:
- если
done
истинно, логическое выражение замыкается и тело цикла вводится без оценки правой части условия.
- если
done
ложно, то вызывается _getch()
. Если возвращается char, выражение будет истинным, и будет введено тело цикла. Если нет доступного символа, _getch()
будет ждать, пока пользователь не введет его. Цикл будет прерван только в том случае, если будет обнаружен конец файла (например, Ctrl+Z вводится в терминальном режиме или cin перенаправляется из файла и достигается его конец).
Если вам нужен неблокирующий ввод с клавиатуры, вам придется использовать _kbhit()
сначала проверить, доступен ли символ, а затем прочитать только символ с _getch()
. Для kbhit()
в Linux вы можете посмотреть здесь.
Редактировать: ваше многопоточное редактирование
Прежде всего, если done
— это переменная, которая используется в обоих потоках (что, по-видимому, так и есть, поскольку она не изменяется в цикле), убедитесь, что она объявлена как atomic
. Если это не так, у вас будет состояние гонки, которое является UB.
Ваше повествование не соответствует коду. Если done
— это когда другой поток завершился, и вы хотите завершить цикл в этот момент, вам нужно зациклиться на !done
.
Кроме того, если вы хотите зацикливаться, пока работает другой поток, но проверить клавиатуру и позволить пользователю прервать код, вам лучше сделать эту проверку в цикле. Кстати, это может быть вариант пройти sleep_for
пару миллисекунд в теле цикла, чтобы не тратить слишком много ресурсов ЦП на запросы к клавиатуре.
Таким образом, код будет иметь такую структуру, как
std::atomic<bool> done(false);
...
thread t(Start, folder_path);
while (!done)
{
if (_kbhit() && ((c = _getch()) != EOF) { // if keystroke available
cout << "Operation aborted" << endl;
exit_signal.set_value(); // assuming this would make t1 return from folder_path()
break;
}
std::this_thread::sleep_for (std::chrono::milliseconds(500));
// update status bar or do other stuff
}
t1.join();
cout << "Operation finished" << endl;
Наконец, я не знаю, что делает exit_signal.set_value();
. Я надеюсь, что он делает что-то, что говорит другому потоку остановить обработку. Если это не так, ваш цикл завершится, но в join()
вам все равно придется ждать завершения другого потока.
person
Christophe
schedule
09.02.2019
done
является атомарным. - person rustyx   schedule 09.02.2019