一个线程,它在控制台上无限打印值,而一个主线程正在从控制台上获取用户输入,但是输入值与该线程的输出混合在一起。
没有给我提示如何进一步发展,但是我无法提出自己的解决方案(因为我是c ++的新手)。
using namespace std;
mutex mtx;
void foo()
{
while (1)
{
usleep(1000000);
cout << "Cake\n";
}
}
int main()
{
mtx.lock();
thread t1(foo);
string x;
while (true)
{
cin >> x;
edit//fflush(stdin);
cout << x << "\n";
}
t1.join();
mtx.unlock();
return 0;
}
编辑1:
好吧,确切地说,我真正想要的是
IN端子(当前)
output:cake (which prints every second)
output:cake
output:cake
output:cake
input:hi
output:hicake (still yet to give the enter it echo's the input to console)
output:cake
我在终端中真正想要的是输入独立于输出
output:cake
output:cake
output:cake
input:hi
output:cake
output:cake
input:hi(waiting still for enter)
//and when enter is pressed it should print to the console
output:hi
output:cake
注意:禁用回声没有帮助。
编辑2: 我发布的答案具有数据处理功能,其中并发操作在给定命令上停止。
答案 0 :(得分:1)
我能够使用所有给定的输入提出解决方案,希望这对某人有帮助。
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <cstring>
#include <mutex>
#include <string>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <thread>
/// reads a character from console without echo.
int getChar()
{
struct termios oldattr;
tcgetattr(STDIN_FILENO, &oldattr);
struct termios newattr = oldattr;
newattr.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
const int ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
return ch;
}
class Console
{
private:
// mutex for console I/O
std::mutex _mtx;
// current input
std::string _input;
// prompt output
std::string _prompt;
public:
Console() {}
Console(const Console &) = delete;
Console &operator=(const Console &) = delete;
std::string read();
void write(const char *text, size_t size);
void write(const char *text) { write(text, strlen(text)); }
void write(const std::string &text) { write(text.c_str(), text.size()); }
};
std::string Console::read()
{
{ // activate prompt
std::lock_guard<std::mutex> lock(_mtx);
_prompt = "> ";
_input.clear();
std::cout << _prompt << std::flush;
}
enum
{
Enter = '\n',
BackSpc = 127
};
for (;;)
{
switch (int c = getChar())
{
case Enter:
{
std::lock_guard<std::mutex> lock(_mtx);
std::string input = _input;
_prompt.clear();
_input.clear();
std::cout << std::endl;
return input;
} // unreachable: break;
case BackSpc:
{
std::lock_guard<std::mutex> lock(_mtx);
if (_input.empty())
break;
_input.pop_back();
std::cout << "\b \b" << std::flush;
}
break;
default:
{
if (c < ' ' || c >= '\x7f')
break;
std::lock_guard<std::mutex> lock(_mtx);
_input += c;
std::cout << (char)c << std::flush;
}
break;
}
}
}
void Console::write(const char *text, size_t len)
{
if (!len)
return;
bool eol = text[len - 1] == '\n';
std::lock_guard<std::mutex> lock(_mtx);
// remove current input echo
if (size_t size = _prompt.size() + _input.size())
{
std::cout
<< std::setfill('\b') << std::setw(size) << ""
<< std::setfill(' ') << std::setw(size) << ""
<< std::setfill('\b') << std::setw(size) << "";
}
// print text
std::cout << text;
if (!eol)
std::cout << std::endl;
// print current input echo
std::cout << _prompt << _input << std::flush;
}
struct Flags //this flag is shared between both the threads
{
// flag: true then exit communication thread and main loop
bool exit;
// flag: true then start data processing
bool start;
// the mini console
Console console;
// constructor.
Flags() : exit(false), start(true) {}
};
void dataProc(Flags &shared)
{
int i = 0;
while (!shared.exit)
{
while (!shared.start)
{
if (shared.exit)
return;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
shared.console.write("Starting data processing.");
for (;;)
{
if (!shared.start || shared.exit)
{
shared.console.write("Data processing stopped.");
while (!shared.start || shared.exit)
{
if (shared.exit)
return;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
shared.console.write("Data processing restarted.");
}
std::this_thread::sleep_for(std::chrono::milliseconds(250));
{
std::ostringstream fmt;
fmt << "Cake " << ++i;
shared.console.write(fmt.str());
}
}
shared.console.write("Data processing done.");
shared.start = false;
}
}
void processInput(const std::string &input, Flags &shared)
{
if (strcasecmp(input.c_str(),"start")==0)
shared.start = true;
else if (strcasecmp(input.c_str(),"stop")==0)
shared.start = false;
else if (strcasecmp(input.c_str(),"exit")==0)
shared.exit = true;
else if (input.size())
shared.console.write("Wrong command!");
}
int main()
{
Flags shared;
std::thread threadProc(&dataProc, std::ref(shared));
while (!shared.exit)
{
shared.console.write("Commands accepted: start stop exit");
std::string input = shared.console.read();
processInput(input, shared);
}
threadProc.join();
return 0;
}
答案 1 :(得分:0)
我建议锁定mtx
和cout
的{{1}}。
cin