РЕДАКТИРОВАТЬ: Можем ли мы повторить вопрос, у меня есть частичный ответ, который я могу опубликовать? И я подумал, что лучший способ справиться с блокирующей природой GetLine - использовать его в потоке. Это действительно отлично подходит для меня - за исключением того, что я не могу остановить поток «внешне» из -за блокировки getLine . Условие, но это основной поток, который хочет, чтобы поток оболочки выключился). Однако, поскольку в то время getLine все еще блокируется, поток не может выйти, поэтому я просто получаю «остановку» - и мне нужно снова нажать Enter, чтобы сделать полный выход, который я нахожу массово раздражающим. Вы можете увидеть то, что я попробовал в приведенном ниже коде, но, к сожалению, это не работает, поскольку мне все еще нужно нажимать введите после «остановки», чтобы получить чистый выход. Ввод - это довольно взломан. /> < /blockquote>
попробовал это, не мог заставить класс для компиляции сначала, но даже позже, что я должен с этим делать? Иметь IDCIN IDCIN (std :: cin, myString) staction stamentiation, а затем используйте idcin , где бы я ни использовал std :: cin ? А что, что, я просто присваиваю myString и cin в конечном итоге выводит его? В любом случае, не удалось заставить это работать. и если вы делаете cin.rdbuf (file.rdbuf ()); at at start - но не если вы хотите изменить поведение во время выполнения (т.е. вы начали использовать cin нормально, а затем хотите, чтобы он выводил файл после некоторого времени; и все же, не хотите файл, нужна строка). /> Вместо того, чтобы облажаться с CIN, вы можете, чтобы ваша программа приняла общую std :: iStream & < /code>. При нормальном запуске просто передайте это cin . Во время модульного теста пропустите его по потоку ввода/вывода вашего собственного творения. Кроме того, возможно, это относится к отдельным экземплярам iStream (то есть cin для нормального запуска программы, что -то еще для тестового запуска) - здесь я бы хотел написать в cin в той же программе. PrettyPrint-Override ">int main() {
using namespace std;
streambuf *backup;
istringstream oss("testdata");
backup = cin.rdbuf();
cin.rdbuf(oss.rdbuf());
string str;
cin >> str;
cout sputn("\r\n", 2);
std::cin.putback('\n');
if (tj.joinable())
{
tj.join();
}
}
void ShellThread::blocking_process_shell(void) {
while( active.load() ) {
printf("> ");
std::getline(std::cin, in_repl_cmd); // detects single press ENTER, and blocks
std::cin.clear();
printf("# %s\n", in_repl_cmd.c_str()); // echo response
}
}
int main(void) {
myshell.start();
std::this_thread::sleep_for(std::chrono::milliseconds(4000));
myshell.stop();
return EXIT_SUCCESS;
}
Итак, что я пытался сделать: std :: cin.clear () , поэтому любые предыдущие ошибки очищаются, а затем попытались записать непосредственно в rdbuf cin с std :: cin.rdbuf ()-> sputn ("\ r \ n", 2); std :: cin.putback ('\ n'); -ничего из этого не помогает с текущим поведением программы:
$ ./test.exe
> hello
# hello
> there
# there
> STOPPING # blocks indefinitely here, have to press ENTER or Ctrl-C *again* if I want it to exit
#
$
В конце концов, я даже не забочусь о том, чтобы писать все так много, все, что я хочу, - это заставить Getline выйти чисто - если бы был метод std :: cin.close () , я думаю, что это можно было бы так или иначе. Или прокси, чтобы заставить getLine < /code> выйти из блокировки ждать? Я собирался написать комментарий, но зачем беспокоиться, никто не заботится достаточно, чтобы больше читать достаточно, чтобы определить, действительно ли вопрос является дубликатом, я думаю, просто с ИИ. Ну, вот вы, тогда: < /p>
// test.cpp
#include // std::cin, std::cout
#include // std::ostringstream
#include // std::ifstream
#include
#include // std::thread
#include // std::atomic
#include // std::istringstream
//#include
#include
#include // std::mutex
// same code with either of these headers:
//#include // Windows only, _getch + kbhit;
#include "linux_conio/linux_conio.h" // git clone https://github.com/Flawww/linux_conio.git
// compile with:
// g++ -g -std=c++11 test.cpp -o test.exe -pthread # Windows
// g++ -g -std=c++11 linux_conio/linux_conio.cpp test.cpp -o test.exe -pthread
class AsyncGetline // https://stackoverflow.com/q/42264216
{
public:
//AsyncGetline is a class that allows for asynchronous CLI getline-style input
//(with 0% CPU usage!), which normal iostream usage does not easily allow.
AsyncGetline()
{
input = "";
sendOverNextLine = true;
continueGettingInput = true;
tj = std::thread([&]()
{
in_thread = true;
//Non-synchronized string of input for the getline calls.
std::string synchronousInput;
char nextCharacter;
int charsRead = 0;
int did_kbhit = 0;
//Get the asynchronous input lines.
do
{
//Start with an empty line.
synchronousInput = "";
//Process input characters one at a time asynchronously, until a new line character is reached.
while (continueGettingInput.load())
{
while( continueGettingInput.load() and (!(did_kbhit = kbhit())) ) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
if (did_kbhit) {
nextCharacter = _getch(); // note, on Windows, on Enter, getting '\r' first (and only)!
//printf(" %d ", nextCharacter);
if (nextCharacter == '\r') {
putchar('\n');
} else {
putchar(nextCharacter);
}
}
//Check for new line character.
// _getch reports '\r', even for copy-paste of CRLF lines
if ((nextCharacter == '\n') or (nextCharacter == '\r'))
{
break;
}
//Since this character is not a new line character, add it to the synchronousInput string.
synchronousInput += nextCharacter;
} // end while
//Be ready to stop retrieving input at any moment.
if (!continueGettingInput.load())
{
break;
}
//Wait until the processing thread is ready to process the next line.
while (continueGettingInput.load() && !sendOverNextLine)
{
//Ensure that the other thread is always yielded to when necessary. Don't sleep here;
//only yield, in order to ensure that the processing will be as responsive as possible.
std::this_thread::yield();
}
//Be ready to stop retrieving input at any moment.
if (!continueGettingInput.load())
{
break;
}
//Safely send the next line of input over for usage in the processing thread.
inputLock.lock();
input = synchronousInput;
inputLock.unlock();
//Signal that although this thread will read in the next line,
//it will not send it over until the processing thread is ready.
sendOverNextLine = false;
} // end do
while (continueGettingInput.load()); // && input != "exit"
in_thread = false;
}); //.detach();
}
//Stop getting asynchronous CLI input.
~AsyncGetline()
{
//Stop the getline thread.
printf("~AsyncGetline destructor 1\n");
continueGettingInput = false;
if (tj.joinable()) {
printf("~AsyncGetline destructor 2\n");
tj.join();
}
}
//Get the next line of input if there is any; if not, sleep for a millisecond and return an empty string.
std::string GetLine()
{
//See if the next line of input, if any, is ready to be processed.
if (sendOverNextLine)
{
//Don't consume the CPU while waiting for input; this_thread::yield()
//would still consume a lot of CPU, so sleep must be used.
std::this_thread::sleep_for(std::chrono::milliseconds(1));
// signal as well
return ">>>NO_LINE ");
fflush(stdout);
prompt_printed = true;
}
if (ag) {
in_repl_cmd = ag->GetLine(); // non-blocking; note: we get empty string here, regardess of if we just pressed ENTER, or if there was no line! though now it says ">>>NO_LINENO_LINE
Подробнее здесь: https://stackoverflow.com/questions/795 ... ng-getline
Напишите конечную строку в STD :: CIN внешне, чтобы сделать его выходом из блокировки GetLine? [дублировать] ⇐ C++
Программы на C++. Форум разработчиков
1743444510
Anonymous
РЕДАКТИРОВАТЬ: Можем ли мы повторить вопрос, у меня есть частичный ответ, который я могу опубликовать? И я подумал, что лучший способ справиться с блокирующей природой GetLine - использовать его в потоке. Это действительно отлично подходит для меня - за исключением того, что я не могу остановить поток «внешне» из -за блокировки getLine . Условие, но это основной поток, который хочет, чтобы поток оболочки выключился). Однако, поскольку в то время getLine все еще блокируется, поток не может выйти, поэтому я просто получаю «остановку» - и мне нужно снова нажать Enter, чтобы сделать полный выход, который я нахожу массово раздражающим. Вы можете увидеть то, что я попробовал в приведенном ниже коде, но, к сожалению, это не работает, поскольку мне все еще нужно нажимать введите после «остановки», чтобы получить чистый выход. Ввод - это довольно взломан. /> < /blockquote>
попробовал это, не мог заставить класс для компиляции сначала, но даже позже, что я должен с этим делать? Иметь IDCIN IDCIN (std :: cin, myString) staction stamentiation, а затем используйте idcin , где бы я ни использовал std :: cin ? А что, что, я просто присваиваю myString и cin в конечном итоге выводит его? В любом случае, не удалось заставить это работать. и если вы делаете cin.rdbuf (file.rdbuf ()); at at start - но не если вы хотите изменить поведение во время выполнения (т.е. вы начали использовать cin нормально, а затем хотите, чтобы он выводил файл после некоторого времени; и все же, не хотите файл, нужна строка). /> Вместо того, чтобы облажаться с CIN, вы можете, чтобы ваша программа приняла общую std :: iStream & < /code>. При нормальном запуске просто передайте это cin . Во время модульного теста пропустите его по потоку ввода/вывода вашего собственного творения. Кроме того, возможно, это относится к отдельным экземплярам iStream (то есть cin для нормального запуска программы, что -то еще для тестового запуска) - здесь я бы хотел написать в cin в той же программе. PrettyPrint-Override ">int main() {
using namespace std;
streambuf *backup;
istringstream oss("testdata");
backup = cin.rdbuf();
cin.rdbuf(oss.rdbuf());
string str;
cin >> str;
cout sputn("\r\n", 2);
std::cin.putback('\n');
if (tj.joinable())
{
tj.join();
}
}
void ShellThread::blocking_process_shell(void) {
while( active.load() ) {
printf("> ");
std::getline(std::cin, in_repl_cmd); // detects single press ENTER, and blocks
std::cin.clear();
printf("# %s\n", in_repl_cmd.c_str()); // echo response
}
}
int main(void) {
myshell.start();
std::this_thread::sleep_for(std::chrono::milliseconds(4000));
myshell.stop();
return EXIT_SUCCESS;
}
Итак, что я пытался сделать: std :: cin.clear () , поэтому любые предыдущие ошибки очищаются, а затем попытались записать непосредственно в rdbuf cin с std :: cin.rdbuf ()-> sputn ("\ r \ n", 2); std :: cin.putback ('\ n'); -ничего из этого не помогает с текущим поведением программы:
$ ./test.exe
> hello
# hello
> there
# there
> STOPPING # blocks indefinitely here, have to press ENTER or Ctrl-C *again* if I want it to exit
#
$
В конце концов, я даже не забочусь о том, чтобы писать все так много, все, что я хочу, - это заставить Getline выйти чисто - если бы был метод std :: cin.close () , я думаю, что это можно было бы так или иначе. Или прокси, чтобы заставить getLine < /code> выйти из блокировки ждать? Я собирался написать комментарий, но зачем беспокоиться, никто не заботится достаточно, чтобы больше читать достаточно, чтобы определить, действительно ли вопрос является дубликатом, я думаю, просто с ИИ. Ну, вот вы, тогда: < /p>
// test.cpp
#include // std::cin, std::cout
#include // std::ostringstream
#include // std::ifstream
#include
#include // std::thread
#include // std::atomic
#include // std::istringstream
//#include
#include
#include // std::mutex
// same code with either of these headers:
//#include // Windows only, _getch + kbhit;
#include "linux_conio/linux_conio.h" // git clone https://github.com/Flawww/linux_conio.git
// compile with:
// g++ -g -std=c++11 test.cpp -o test.exe -pthread # Windows
// g++ -g -std=c++11 linux_conio/linux_conio.cpp test.cpp -o test.exe -pthread
class AsyncGetline // https://stackoverflow.com/q/42264216
{
public:
//AsyncGetline is a class that allows for asynchronous CLI getline-style input
//(with 0% CPU usage!), which normal iostream usage does not easily allow.
AsyncGetline()
{
input = "";
sendOverNextLine = true;
continueGettingInput = true;
tj = std::thread([&]()
{
in_thread = true;
//Non-synchronized string of input for the getline calls.
std::string synchronousInput;
char nextCharacter;
int charsRead = 0;
int did_kbhit = 0;
//Get the asynchronous input lines.
do
{
//Start with an empty line.
synchronousInput = "";
//Process input characters one at a time asynchronously, until a new line character is reached.
while (continueGettingInput.load())
{
while( continueGettingInput.load() and (!(did_kbhit = kbhit())) ) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
if (did_kbhit) {
nextCharacter = _getch(); // note, on Windows, on Enter, getting '\r' first (and only)!
//printf(" %d ", nextCharacter);
if (nextCharacter == '\r') {
putchar('\n');
} else {
putchar(nextCharacter);
}
}
//Check for new line character.
// _getch reports '\r', even for copy-paste of CRLF lines
if ((nextCharacter == '\n') or (nextCharacter == '\r'))
{
break;
}
//Since this character is not a new line character, add it to the synchronousInput string.
synchronousInput += nextCharacter;
} // end while
//Be ready to stop retrieving input at any moment.
if (!continueGettingInput.load())
{
break;
}
//Wait until the processing thread is ready to process the next line.
while (continueGettingInput.load() && !sendOverNextLine)
{
//Ensure that the other thread is always yielded to when necessary. Don't sleep here;
//only yield, in order to ensure that the processing will be as responsive as possible.
std::this_thread::yield();
}
//Be ready to stop retrieving input at any moment.
if (!continueGettingInput.load())
{
break;
}
//Safely send the next line of input over for usage in the processing thread.
inputLock.lock();
input = synchronousInput;
inputLock.unlock();
//Signal that although this thread will read in the next line,
//it will not send it over until the processing thread is ready.
sendOverNextLine = false;
} // end do
while (continueGettingInput.load()); // && input != "exit"
in_thread = false;
}); //.detach();
}
//Stop getting asynchronous CLI input.
~AsyncGetline()
{
//Stop the getline thread.
printf("~AsyncGetline destructor 1\n");
continueGettingInput = false;
if (tj.joinable()) {
printf("~AsyncGetline destructor 2\n");
tj.join();
}
}
//Get the next line of input if there is any; if not, sleep for a millisecond and return an empty string.
std::string GetLine()
{
//See if the next line of input, if any, is ready to be processed.
if (sendOverNextLine)
{
//Don't consume the CPU while waiting for input; this_thread::yield()
//would still consume a lot of CPU, so sleep must be used.
std::this_thread::sleep_for(std::chrono::milliseconds(1));
// signal as well
return ">>>NO_LINE ");
fflush(stdout);
prompt_printed = true;
}
if (ag) {
in_repl_cmd = ag->GetLine(); // non-blocking; note: we get empty string here, regardess of if we just pressed ENTER, or if there was no line! though now it says ">>>NO_LINENO_LINE
Подробнее здесь: [url]https://stackoverflow.com/questions/79545332/write-endline-string-to-stdcin-externally-to-make-it-exit-blocking-getline[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия