Is there a way to break out of an infinite loop while it's running without using Ctrl + C? I would like to implement such a method in other programs. Like in this example program:
#include <iostream>
int main()
{
int x = 0;
for(;;)
cout << x;
}
is there a way to keep the for loop going but break it with some key at any time. I should also explain I understand using break;, but I want the loop to keep going. If I use a break condition like this, the for-loop would stop and wait for a response.
#include <iostream>
int main()
{
int x = 0;
for(;;)
{
cout << x;
if(getch()=='n')
break;
}
}
Find some condition that you wish to break out of the loop when encountered then use the break keyword:
#include <iostream>
int main()
{
int x = 0;
for(;;)
cout << x;
if(/* break condition*/){
break;
}
}
There's nothing stopping you from implementing the break condition by detecting a particular keyboard input from a user.
EDIT: From your edited question it appears you want to have loop continue running all the time and not stopping waiting for user input. The only way I can think of doing this is to spawn a new thread that listens for user input that alters a variable that gets detected in the break condition of your main thread.
If you have access to c++11 and the new thread library you could do something like this:
#include <iostream>
#include <thread>
bool break_condition = false;
void looper(){
for(;;){
std::cout << "loop running" << std::endl;
if(break_condition){
break;
}
}
}
void user_input(){
if(std::cin.get()=='n'){
break_condition = true;
}
}
int main(){
//create a thread for the loop and one for listening for input
std::thread loop_thread(looper);
std::thread user_input_thread(user_input);
//synchronize threads
loop_thread.join();
user_input_thread.join();
std::cout << "loop successfully broken out of" << std::endl;
return 0;
}
If you do decide to take a threading approach be careful as there's issues in multithreaded code that don't exist in single threaded code and they can sometimes be really nasty.
You are looking for continue I think
#include <iostream>
int main()
{
int x = 0;
for(;;)
{
cout << x;
if(getch()=='n')
continue;
}
}
Related
I am trying to make a program that uses shared resources, but all I get in the is std::logic_error. I think I am not using the mutex in the right way. Here is a snippet of the code.
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
struct camera {
std::string name;
std::string mac;
bool accessStatus;
};
class service {
public:
service(){};
void run();
private:
mutable std::mutex _mutex;
};
void service::run()
{
unsigned char option;
// some dummy camera object
camera camera_object;
camera_object.name = "camera_name";
camera_object.mac = "B6:24:3D:4C:00:9B";
camera_object.accessStatus = true;
// a vector of objects
std::vector<camera> cameras;
cameras.push_back(camera_object);
std::thread TT([&](){
while (true) {
// dummy condition
if (1 == 1) {
std::cout << cameras.size();
}
{
std::unique_lock<std::mutex> mlock(_mutex);
std::cout << "Choose an option:\n"
<< "\t 1. add one more camera \n"
<< "\t 2. get the theme \n"
<< std::flush;
option = getchar();
switch (option) {
case '1':
cameras.push_back(camera_object);
break;
case '2':
std::cout << "Not yet implemented\n" << std::flush;
break;
default:
std::cout << "Invalid input\n" << std::flush;
break;
}
}
// don't waste CPU resources
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
system("clear");
}
});
TT.detach();
}
int main() {
service sv;
sv.run();
return 0;
}
Sometimes when I run it it just returns segmentation fault, but other times it let me choose an option, but after I choose it I get std::logic_error. I am trying to understand how mutex and multithreading works, but I have a hard time on this one.
Edit: the shared resource is the cameras vector. I am doing this program just to learn, it does not have a real objective. The condition 1==1 is there just to be sure that is always prints the vector size.
Your problem isn't really the threading, it's the fact that your lambda captures by reference a cameras vector that goes out of scope and is destroyed. You can reproduce this deterministically even with a single thread:
std::function<void(void)> foo()
{
std::vector<int> out_of_scope;
return [&]() { out_of_scope.push_back(42); };
}
anywhere you call the returned std::function will have Undefined Behaviour, because the vector no longer exists. Invoking this UB in a different thread doesn't change anything.
If you're going to have shared state, you have to make sure it lives at least as long as the threads using it. Just make the cameras vector a member of service alongside the mutex that protects it. Or join the thread so the vector doesn't go out of scope until after the thread exits. Either will work.
I'm new to C++ and am trying to have two threads run:
i) Thread that keeps looping until an atomic bool is flipped.
ii) A thread that polls for input from keyboard and flips the atomic bool.
I seem to be unable to get std::cin.get() to react to an input unless it is assigned its' own thread (like below). Why? Would it not then be set from the parent main thread?
#include <iostream>
#include <iomanip> // To set decimal places.
#include <thread> //std::thread
#include <atomic> //for atomic boolean shared between threads.
#include <math.h>
#define USE_MATH_DEFINES //For PI
std::atomic<bool> keepRunning(false); //set to false to avoid compiler optimising away.
void loop(){
int t = 1;
while(!keepRunning.load(std::memory_order_acquire)) //lower cost than directly polling atomic bool?
{
//Write sine wave output to console.
std::cout << std::setprecision(3) << sin(M_PI * 2 * t/100) << std::endl;
(t<101)? t++ : t = 1;
}
}
//This works, as opposed to stopping in main.
void countSafe(){
int j = 1;
while (j<1E7)
{
j++;
}
keepRunning.store(true, std::memory_order_release); //ends the loop thread.
}
int main(){
std::thread first (loop); //start the loop thread
std::thread second (countSafe); //start the countSafe thread. Without this it doesn't work.
//Why does polling for std::cin.get() here not work?
//std::cin.get(); //wait for key press. puts in buffer..?
//keepRunning.store(true, std::memory_order_release); //Set stop to true.
second.join(); //pause to join.
first.join(); //pause to join
return 0;
}
I'm not quite sure what your problem is, but use of cin.get() might be part of it. Let's simplify with this code:
#include <iostream>
using namespace std;
int main(int, char **) {
cout << "Type something: ";
cin.get();
cout << "Done.\n";
}
Try that code and run it. Then type a single character. Chances are that the code won't recognize it. And you can type all you want until you hit return.
This is complicated, but your program doesn't actually receive the characters until you hit return unless you play other games. Like I said, it's complicated.
It's possible behavior is different on Windows, but this is the behavior on Mac and Linux.
So is it "not working" because you tried typing a space but you really need to use Return?
I have a question about the correctness of my code.
I'm making a app which is run as a daemon, it do some code in interval, code looks:
#include <iostream>
#include <thread>
using namespace std;
int main() {
thread([=]() {
while (true) {
try {
cout << "log" << endl;
this_thread::sleep_for(chrono::milliseconds(3000));
}
catch (...) {
cout << "Some errors here :/" << endl;
}
}
}).detach();
while (true);
}
I'm worried weather this code is optimal, because in top I can see, that this program uses about 80% of the CPU.
Can I correct something?
Is my code equivalent to this one:
https://stackoverflow.com/a/21058232/5334833?
It appears that while(true); is UB.
You might just get rid of thread BTW:
int main() {
while (true) {
try {
std::cout << "log" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
}
catch (...) {
std::cout << "Some errors here :/" << std::endl;
}
}
}
while(true); will cause your main thread to continuously loop and use 100% of a single CPU.
Assuming you are on Linux you can just call pause() instead which will suspend your main thread until a signal arrives.
As you aren't actually using your main thread is there a reason you are spawning a new thread at all? Can you just do your work in the main thread?
i have an infinite loop that should be ended if i pressed any key. The program runs in linux. I have stumbled upon a function Here is a bit of my code :
int main(){
While(1){
ParseData(); //writing data to a text file
}
return 0;
}
so i know that i can terminate the process by using ctrl + c in terminal, but it seems that it will interrupt the writing process so the datas are not written completely halfway through the process. I read that i need to use function from ncurses library , but i can't quite understand any.
Can someone help me with it? Thanks!
You can declare an atomic_bool and move your main loop to another thread. Now you can wait with a simple cin, once the user presses any key you exit your loop.
std::atomic_boolean stop = false;
void loop() {
while(!stop)
{
ParseData(); // your loop body here
}
}
int main() {
std::thread t(loop); // Separate thread for loop.
// Wait for input character (this will suspend the main thread, but the loop
// thread will keep running).
std::cin.get();
// Set the atomic boolean to true. The loop thread will exit from
// loop and terminate.
stop = true;
t.join();
return 0;
}
Why do you need a key to exit a program that didn't finish writing to a file, even if you make the loop exits on key press it will interrupt the file writing too if not finished.
Why you just exit the loop when the data finishes writing to the file, like the following:
isFinished = false;
While(!isFinished ){
ParseData(); //writing data to a text file
//after data finsihes
isFinished = false;
}
thread.cpp
#include <atomic>
#include <iostream>
#include <thread>
std::atomic<bool> dataReady(false);
void waitingForWork(){
std::cout << "Waiting... " << std::endl;
while ( !dataReady.load() ){
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
std::cout << "Work done " << std::endl;
}
int main(){
std::cout << std::endl;
std::thread t1(waitingForWork);
std::cout << "Press Enter to Exit" << std::endl;
std::cin.get();
dataReady= true;
t1.join();
std::cout << "\n\n";
}
g++ -o thread thread.cpp -std=c++11 -pthread
The C way actually (include conio.h ):
char key;
while (1)
{
key = _getch();
// P to exit
if (key == 'p' || key == 'P')
{
writer.close();
exit(1);
}
}
I am trying to create a function that will be done many times over and over but with a pause in between each cycle.
I have tried to use "sleep" but that pauses the console. And I have searched online and only found answers that paused the console during usual.
Code:
int i;
for(i=0; i<500; i++) {
std::cout << "Hello" << std::endl;
}
How can I make it print "Hello" 500 times and as well allow the user to use the console while it is doing the said function?
As some people commented, you need to create an async task in order to do some work while still handling user input.
The following is a minimal, working example about how to acomplish this task by using a thread. It is based on boost so you'll have to link it using -lboost_thread lboost_system:
g++ test.cpp -lboost_thread -lboost_system -o test
The code has several comments in order to explain what you should do:
#include <queue>
#include <iostream>
#include <boost/thread.hpp>
// set by the main thread when the user enters 'quit'
bool stop = false;
boost::mutex stopMutex; // protect the flag!
// the function that runs in a new thread
void thread_function() {
// the following is based on the snippet you wrote
int i;
for(i=0; i<500; i++) {
// test if I have to stop on each loop
{
boost::mutex::scoped_lock lock(stopMutex);
if (stop) {
break;
}
}
// your task
std::cout << "Hello" << std::endl;
// sleep a little
::usleep(1000000);
}
}
int main() {
std::string str;
boost::thread t(thread_function);
while(true) {
std::cout << "Type 'quit' to exit: ";
// will read user input
std::getline(std::cin, str);
if (str == "quit") {
// the user wants to quit the program, set the flag
boost::mutex::scoped_lock lock(stopMutex);
stop = true;
break;
}
}
// wait for the async task to finish
t.join();
return 0;
}