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.
Related
I'm studying concurrency in C++ and I'm trying to implement a multithreaded callback registration system. I came up with the following code, which is supposed to accept registration requests until an event occurs. After that, it should execute all the registered callbacks in order with which they were registered. The registration order doesn't have to be deterministic.
The code doesn't work as expected. First of all, it rarely prints the "Pushing callback with id" message. Secondly, it sometimes hangs (a deadlock caused by a race condition, I assume). I'd appreciate help in figuring out what's going on here. If you see that I overcomplicate some parts of the code or misuse some pieces, please also point it out.
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <queue>
#include <thread>
class CallbackRegistrar{
public:
void registerCallbackAndExecute(std::function<void()> callback) {
if (!eventTriggered) {
std::unique_lock<std::mutex> lock(callbackMutex);
auto saved_id = callback_id;
std::cout << "Pushing callback with id " << saved_id << std::endl;
registeredCallbacks.push(std::make_pair(callback_id, callback));
++callback_id;
callbackCond.wait(lock, [this, saved_id]{return releasedCallback.first == saved_id;});
releasedCallback.second();
callbackExecuted = true;
eventCond.notify_one();
}
else {
callback();
}
}
void registerEvent() {
eventTriggered = true;
while (!registeredCallbacks.empty()) {
releasedCallback = registeredCallbacks.front();
callbackCond.notify_all();
std::unique_lock<std::mutex> lock(eventMutex);
eventCond.wait(lock, [this]{return callbackExecuted;});
callbackExecuted = false;
registeredCallbacks.pop();
}
}
private:
std::queue<std::pair<unsigned, std::function<void()>>> registeredCallbacks;
bool eventTriggered{false};
bool callbackExecuted{false};
std::mutex callbackMutex;
std::mutex eventMutex;
std::condition_variable callbackCond;
std::condition_variable eventCond;
unsigned callback_id{1};
std::pair<unsigned, std::function<void()>> releasedCallback;
};
int main()
{
CallbackRegistrar registrar;
std::thread t1(&CallbackRegistrar::registerCallbackAndExecute, std::ref(registrar), []{std::cout << "First!\n";});
std::thread t2(&CallbackRegistrar::registerCallbackAndExecute, std::ref(registrar), []{std::cout << "Second!\n";});
registrar.registerEvent();
t1.join();
t2.join();
return 0;
}
This answer has been edited in response to more information being provided by the OP in a comment, the edit is at the bottom of the answer.
Along with the excellent suggestions in the comments, the main problem that I have found in your code is with the callbackCond condition variable wait condition that you have set up. What happens if releasedCallback.first does not equal savedId?
When I have run your code (with a thread-safe queue and eventTriggered as an atomic) I found that the problem was in this wait function, if you put a print statement in that function you will find that you get something like this:
releasedCallback.first: 0, savedId: 1
This then waits forever.
In fact, I've found that the condition variables used in your code aren't actually needed. You only need one, and it can live inside the thread-safe queue that you are going to build after some searching ;)
After you have the thread-safe queue, the code from above can be reduced to:
class CallbackRegistrar{
public:
using NumberedCallback = std::pair<unsigned int, std::function<void()>>;
void postCallback(std::function<void()> callback) {
if (!eventTriggered)
{
std::unique_lock<std::mutex> lock(mutex);
auto saved_id = callback_id;
std::cout << "Pushing callback with id " << saved_id << std::endl;
registeredCallbacks.push(std::make_pair(callback_id, callback));
++callback_id;
}
else
{
while (!registeredCallbacks.empty())
{
NumberedCallback releasedCallback;
registeredCallbacks.waitAndPop(releasedCallback);
releasedCallback.second();
}
callback();
}
}
void registerEvent() {
eventTriggered = true;
}
private:
ThreadSafeQueue<NumberedCallback> registeredCallbacks;
std::atomic<bool> eventTriggered{false};
std::mutex mutex;
unsigned int callback_id{1};
};
int main()
{
CallbackRegistrar registrar;
std::vector<std::thread> threads;
for (int i = 0; i < 10; i++)
{
threads.push_back(std::thread(&CallbackRegistrar::postCallback,
std::ref(registrar),
[i]{std::cout << std::to_string(i) <<"\n";}
));
}
registrar.registerEvent();
for (auto& thread : threads)
{
thread.join();
}
return 0;
}
I'm not sure if this does exactly what you want, but it doesn't deadlock. It's a good starting point in any case, but you need to bring your own implementation of ThreadSafeQueue.
Edit
This edit is in response to the comment by the OP stating that "once the event occurs, all the callbacks should be executed in [the] order that they've been pushed to the queue and by the same thread that registered them".
This was not mentioned in the original question post. However, if that is the required behaviour then we need to have a condition variable wait in the postCallback method. I think this is also the reason why the OP had the condition variable in the postCallback method in the first place.
In the code below I have made a few edits to the callbacks, they now take input parameters. I did this to print some useful information while the code is running so that it is easier to see how it works, and, importantly how the condition variable wait is working.
The basic idea is similar to what you had done, I've just trimmed out the stuff you didn't need.
class CallbackRegistrar{
public:
using NumberedCallback = std::pair<unsigned int, std::function<void(int, int)>>;
void postCallback(std::function<void(int, int)> callback, int threadId) {
if (!m_eventTriggered)
{
// Lock the m_mutex
std::unique_lock<std::mutex> lock(m_mutex);
// Save the current callback ID and push the callback to the queue
auto savedId = m_currentCallbackId++;
std::cout << "Pushing callback with ID " << savedId << "\n";
m_registeredCallbacks.push(std::make_pair(savedId, callback));
// Wait until our thread's callback is next in the queue,
// this will occur when the ID of the last called callback is one less than our saved callback.
m_conditionVariable.wait(lock, [this, savedId, threadId] () -> bool
{
std::cout << "Waiting on thread " << threadId << " last: " << m_lastCalledCallbackId << ", saved - 1: " << (savedId - 1) << "\n";
return (m_lastCalledCallbackId == (savedId - 1));
});
// Once we are finished waiting, get the callback out of the queue
NumberedCallback retrievedCallback;
m_registeredCallbacks.waitAndPop(retrievedCallback);
// Update last callback ID and call the callback
m_lastCalledCallbackId = retrievedCallback.first;
retrievedCallback.second(m_lastCalledCallbackId, threadId);
// Notify one waiting thread
m_conditionVariable.notify_one();
}
else
{
// If the event is already triggered, call the callback straight away
callback(-1, threadId);
}
}
void registerEvent() {
// This is all we have to do here.
m_eventTriggered = true;
}
private:
ThreadSafeQueue<NumberedCallback> m_registeredCallbacks;
std::atomic<bool> m_eventTriggered{ false};
std::mutex m_mutex;
std::condition_variable m_conditionVariable;
unsigned int m_currentCallbackId{ 1};
std::atomic<unsigned int> m_lastCalledCallbackId{ 0};
};
The main function is as above, except I am creating 100 threads instead of 10, and I have made the callback print out information about how it was called.
for (int createdThreadId = 0; createdThreadId < 100; createdThreadId++)
{
threads.push_back(std::thread(&CallbackRegistrar::postCallback,
std::ref(registrar),
[createdThreadId](int registeredCallbackId, int callingThreadId)
{
if (registeredCallbackId < 0)
{
std::cout << "Callback " << createdThreadId;
std::cout << " called immediately, from thread: " << callingThreadId << "\n";
}
else
{
std::cout << "Callback " << createdThreadId;
std::cout << " called from thread " << callingThreadId;
std::cout << " after being registered as " << registeredCallbackId << "\n";
}
},
createdThreadId));
}
I am not entirely sure why you want to do this, as it seems to defeat the point of having multiple threads, although I may be missing something there. But, regardless, I hope this helps you to understand better the problem you are trying to solve.
Experimenting with this code some more, I found out why the "Pushing callback with id " part was rarely printed. It's because the call to registrar.registerEvent from the main thread was usually faster than the calls to registerCallbackAndExecute from separate threads. Because of that, the condition if (!eventTriggered) was almost never fulfilled (eventTriggered had been set to true in the registerEvent method) and hence all calls to registerCallbackAndExecute were falling into the else branch and executing straightaway.
Then, the program sometimes also didn't finish, because of a race condition between registerEvent and registerCallbackAndExecute. Sometimes, registerEvent was being called after the check if (!eventTriggered) but before pushing the callback to the queue. Then, registerEvent completed instantly (as the queue was empty) while the thread calling registerCallbackAndExecute was pushing the callback to the queue. The latter thread then kept waiting forever for the event (that had already happened) to happen.
I have used mutex in inherited classes but seems it does not work as I expected with threads. Please have a look at below code:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
// mutex::lock/unlock
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::thread
#include <mutex> // std::mutex
typedef unsigned int UINT32t;
typedef int INT32t;
using namespace std;
class Abstract {
protected:
std::mutex mtx;
};
class Derived: public Abstract
{
public:
void* write( void* result)
{
UINT32t error[1];
UINT32t data = 34;
INT32t length = 0;
static INT32t counter = 0;
cout << "\t before Locking ..." << " in thread" << endl;
mtx.lock();
//critical section
cout << "\t After Create " << ++ counter << " device in thread" << endl;
std::this_thread::sleep_for(1s);
mtx.unlock();
cout << "\t deallocated " << counter << " device in thread" << endl;
pthread_exit(result);
}
};
void* threadTest1( void* result)
{
Derived dev;
dev.write(nullptr);
}
int main()
{
unsigned char byData[1024] = {0};
ssize_t len;
void *status = 0, *status2 = 0;
int result = 0, result2 = 0;
pthread_t pth, pth2;
pthread_create(&pth, NULL, threadTest1, &result);
pthread_create(&pth2, NULL, threadTest1, &result2);
//wait for all kids to complete
pthread_join(pth, &status);
pthread_join(pth2, &status2);
if (status != 0) {
printf("result : %d\n",result);
} else {
printf("thread failed\n");
}
if (status2 != 0) {
printf("result2 : %d\n",result2);
} else {
printf("thread2 failed\n");
}
return -1;
}
so the result is:
*Four or five arguments expected.
before Locking ... in thread
After Create 1 device in thread
before Locking ... in thread
After Create 2 device in thread
deallocated 2 device in thread
deallocated 2 device in thread
thread failed
thread2 failed
*
So here we can see that second thread comes to critical section before mutex was deallocated.
The string "After Create 2 device in thread" says about that.
If it comes to critical section before mutex is deallocated it means mutex works wrong.
If you have any thoughts please share.
thanks
The mutex itself is (probably) working fine (I'd recommend you to use std::lock_guard though), but both threads create their own Derived object, hence, they don't use the same mutex.
Edit: tkausl's answer is correct -- however, even if you switch to using a global mutex, the output may not change because of the detail in my answer so I'm leaving it here. In other words, there are two reasons why the output may not be what you expect, and you need to fix both.
Note in particular these two lines:
mtx.unlock();
cout << "\t deallocated " << counter << " device in thread" << endl;
You seem to be under the impression that these two lines will be run one right after the other, but there is no guarantee that this will happen in a preemptive multithreading environment. What can happen instead is that right after mtx.unlock() there could be a context switch to the other thread.
In other words, the second thread is waiting for the mutex to unlock, but the first thread isn't printing the "deallocated" message before the second thread preempts it.
The simplest way to get the output you expect would be to swap the order of these two lines.
You shall declare your mutex as a global variable and initiate it before calling pthread_create. You created two threads using pthread_create and both of them create their own mutex so there is absolutely no synchronization between them.
I am running an asynchronous task and want to cancel it when a certain condition (bool) is met.
void MyClass::createTask()
{
this->future = std::async(std::launch::async, [this](){
while(this->CONDITION == false)
{
// do work
}
});
}
void MyClass::cancelTask()
{
this->CONDITION = true;
this->future.get();
}
Obviously, calling MyClass::cancelTask() would cause a data-race, because this->CONDITION is being written to and read from at the same time. So the first thing that came to my mind is to use a std::mutex. However that would mean that the task has to lock and unlock the mutex on every new iteration of the while-loop. Since the async task is performance critical, this seems like a bad choice.
Is there a cleaner, and especially a more perfomant way to achieve what I am trying to do? Switching from std::async to std::thread would be ok if it enabled an efficient solution.
As far as I know there is no elegant way to close a thread/async task in C++.
A simple way is to use std::atomic<bool> or std::atomic_flag instead of a mutex.
If you are familiar with boost library, than you could use boost::thread with interruption_points.
I have a solution for this kind of requeirements. I use std::mutex, std::condition_variable and std::unique_lock<std::mutex> to create tow methods: pauseThread and resumeThread.
The idea is use the condition_variable and unique_lock to make the thread wait for a time, for example 5 seconds, and after the time os over the thread continue its execution. But, if you want to interrupt the condition_variable you could use its method notify_one().
Using your code, and continue with your idea, i made some changes to your class:
MODIFICATION: I modify the flag bKeepRunning.
MyClass.h
#include <mutex>
#include <chrono>
#include <future>
#include <atomic>
class MyClass
{
std::atomic<bool> bKeepRunning;
std::mutex mtx_t;
std::condition_variable cv_t;
std::future<void> _future;
public:
MyClass();
~MyClass();
void createTask();
void stopTask();
void pauseThread(int time);
void resumeThread();
}
MyClass.cpp
#include "MyClass.h"
#include <iostream>
using namespace std;
MyClass::MyClass()
{
bKeepRunning = false;
}
MyClass::~MyClass()
{
}
void MyClass::createTask()
{
bKeepRunning = true;
_future = std::async(std::launch::async, [this]() {
int counter = 0;
cout << "Thread running" << endl;
while (bKeepRunning)
{
counter++;
cout << "Asynchronous thread counter = [" << counter << "]" << endl;
this->pauseThread(5);//Wait for 5 seconds
}
cout << "Thread finished." << endl;
});
}
void MyClass::stopTask()
{
cout << "Stoping Thread." << endl;
bKeepRunning = false;
resumeThread();
}
void MyClass::pauseThread(int time)
{
std::unique_lock<std::mutex> lck_t(mtx_t);
cv_t.wait_for(lck_t, chrono::seconds(time));
}
void MyClass::resumeThread()
{
cout << "Resumming thread" << endl;
cv_t.notify_one();
}
I made a console sample to show how it works:
Main.cpp
#include <iostream>
#include <sstream>
#include <string>
#include "MyClass.h"
using namespace std;
int main(int argc, char* argv[])
{
MyClass app;
char line[80];
cout << "Press Enter to stop thread." << endl;
app.createTask();
cin.getline(line,80);
app.stopTask();
}
If you need some other period of time to pause your thread, you can try to change the interval and time of chrono::seconds(time) to, for example, chrono::milliseconds(time) that is using milliseconds.+
At the end, if you execute this sample, you could get an output like:
I have a c++ class that allocates a lot of memory. It does this by calling a third-party library that is designed to crash if it cannot allocate the memory, and sometimes my application creates several instances of my class in parallel threads. With too many threads I have a crash.
My best idea for a solution is to make sure that there are never, say, more than three instances running at the same time. (Is this a good idea?)
And my current best idea for implementing that is to use a boost mutex. Something along the lines of the following pseudo-code,
MyClass::MyClass(){
my_thread_number = -1; //this is a class variable
while (my_thread_number == -1)
for (int i=0; i < MAX_PROCESSES; i++)
if(try_lock a mutex named i){
my_thread_number = i;
break;
}
//Now I know that my thread has mutex number i and it is allowed to run
}
MyClass::~MyClass(){
release mutex named my_thread_number
}
As you see, I am not quite sure of the exact syntax for mutexes here.. So summing up, my questions are
Am I on the right track when I want to solve my memory error by limiting the number of threads?
If yes, Should I do it with mutexes or by other means?
If yes, Is my algorithm sound?
Is there a nice example somewhere of how to use try_lock with boost mutexes?
Edit: I realized I am talking about threads, not processes.
Edit: I am involved in building an application that can run on both linux and Windows...
UPDATE My other answer addresses scheduling resources among threads (after the question was clarified).
It shows both a semaphore approach to coordinate work among (many) workers, and a thread_pool to limit workers in the first place and queue the work.
On linux (and perhaps other OSes?) you can use a lock file idiom (but it's not supported with some file-systems and old kernels).
I would suggest to use Interprocess synchronisation objects.
E.g., using a Boost Interprocess named semaphore:
#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread.hpp>
#include <cassert>
int main()
{
using namespace boost::interprocess;
named_semaphore sem(open_or_create, "ffed38bd-f0fc-4f79-8838-5301c328268c", 0ul);
if (sem.try_wait())
{
std::cout << "Oops, second instance\n";
}
else
{
sem.post();
// feign hard work for 30s
boost::this_thread::sleep_for(boost::chrono::seconds(30));
if (sem.try_wait())
{
sem.remove("ffed38bd-f0fc-4f79-8838-5301c328268c");
}
}
}
If you start one copy in the back ground, new copies will "refuse" to start ("Oops, second instance") for about 30s.
I have a feeling it might be easier to reverse the logic here. Mmm. Lemme try.
some time passes
Hehe. That was more tricky than I thought.
The thing is, you want to make sure that the lock doesn't remain when your application is interrupted or killed. In the interest of sharing the techniques for portably handling the signals:
#include <boost/interprocess/sync/named_semaphore.hpp>
#include <boost/thread.hpp>
#include <cassert>
#include <boost/asio.hpp>
#define MAX_PROCESS_INSTANCES 3
boost::interprocess::named_semaphore sem(
boost::interprocess::open_or_create,
"4de7ddfe-2bd5-428f-b74d-080970f980be",
MAX_PROCESS_INSTANCES);
// to handle signals:
boost::asio::io_service service;
boost::asio::signal_set sig(service);
int main()
{
if (sem.try_wait())
{
sig.add(SIGINT);
sig.add(SIGTERM);
sig.add(SIGABRT);
sig.async_wait([](boost::system::error_code,int sig){
std::cerr << "Exiting with signal " << sig << "...\n";
sem.post();
});
boost::thread sig_listener([&] { service.run(); });
boost::this_thread::sleep_for(boost::chrono::seconds(3));
service.post([&] { sig.cancel(); });
sig_listener.join();
}
else
{
std::cout << "More than " << MAX_PROCESS_INSTANCES << " instances not allowed\n";
}
}
There's a lot that could be explained there. Let me know if you're interested.
NOTE It should be quite obvious that if kill -9 is used on your application (forced termination) then all bets are off and you'll have to either remove the Name Semaphore object or explicitly unlock it (post()).
Here's a testrun on my system:
sehe#desktop:/tmp$ (for a in {1..6}; do ./test& done; time wait)
More than 3 instances not allowed
More than 3 instances not allowed
More than 3 instances not allowed
Exiting with signal 0...
Exiting with signal 0...
Exiting with signal 0...
real 0m3.005s
user 0m0.013s
sys 0m0.012s
Here's a simplistic way to implement your own 'semaphore' (since I don't think the standard library or boost have one). This chooses a 'cooperative' approach and workers will wait for each other:
#include <boost/thread.hpp>
#include <boost/phoenix.hpp>
using namespace boost;
using namespace boost::phoenix::arg_names;
void the_work(int id)
{
static int running = 0;
std::cout << "worker " << id << " entered (" << running << " running)\n";
static mutex mx;
static condition_variable cv;
// synchronize here, waiting until we can begin work
{
unique_lock<mutex> lk(mx);
cv.wait(lk, phoenix::cref(running) < 3);
running += 1;
}
std::cout << "worker " << id << " start work\n";
this_thread::sleep_for(chrono::seconds(2));
std::cout << "worker " << id << " done\n";
// signal one other worker, if waiting
{
lock_guard<mutex> lk(mx);
running -= 1;
cv.notify_one();
}
}
int main()
{
thread_group pool;
for (int i = 0; i < 10; ++i)
pool.create_thread(bind(the_work, i));
pool.join_all();
}
Now, I'd say it's probably better to have a dedicated pool of n workers taking their work from a queue in turns:
#include <boost/thread.hpp>
#include <boost/phoenix.hpp>
#include <boost/optional.hpp>
using namespace boost;
using namespace boost::phoenix::arg_names;
class thread_pool
{
private:
mutex mx;
condition_variable cv;
typedef function<void()> job_t;
std::deque<job_t> _queue;
thread_group pool;
boost::atomic_bool shutdown;
static void worker_thread(thread_pool& q)
{
while (auto job = q.dequeue())
(*job)();
}
public:
thread_pool() : shutdown(false) {
for (unsigned i = 0; i < boost::thread::hardware_concurrency(); ++i)
pool.create_thread(bind(worker_thread, ref(*this)));
}
void enqueue(job_t job)
{
lock_guard<mutex> lk(mx);
_queue.push_back(std::move(job));
cv.notify_one();
}
optional<job_t> dequeue()
{
unique_lock<mutex> lk(mx);
namespace phx = boost::phoenix;
cv.wait(lk, phx::ref(shutdown) || !phx::empty(phx::ref(_queue)));
if (_queue.empty())
return none;
auto job = std::move(_queue.front());
_queue.pop_front();
return std::move(job);
}
~thread_pool()
{
shutdown = true;
{
lock_guard<mutex> lk(mx);
cv.notify_all();
}
pool.join_all();
}
};
void the_work(int id)
{
std::cout << "worker " << id << " entered\n";
// no more synchronization; the pool size determines max concurrency
std::cout << "worker " << id << " start work\n";
this_thread::sleep_for(chrono::seconds(2));
std::cout << "worker " << id << " done\n";
}
int main()
{
thread_pool pool; // uses 1 thread per core
for (int i = 0; i < 10; ++i)
pool.enqueue(bind(the_work, i));
}
PS. You can use C++11 lambdas instead boost::phoenix there if you prefer.
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;
}
}