I've recently tried cpp, in the thing I'm making I'm trying to make it so that a variable with the value of 20 is subtracted by 1 every second, but I also need the machine to be waiting for an input from the user. I tried using for loops but they won't proceed until the input is placed or until the variable runs out. I looked at clock but they don't seem to fit my need, or maybe I just misunderstood their purpose.
Any suggestions?
As has already been suggested in the comments, threading is one way to do this. There is a nice self-contained example here (which I've borrowed from in the code below).
In the code below an asynchronous function is launched. Details on these here. This returns a future object which will contain the result once the job has finished.
In this case the job is listening to cin (typically the terminal input) and will return when some data is entered (i.e. when enter is pressed).
In the meantime the while loop will be running which keeps a track of how much time has passed, decrements the counter, and also returns if the asynchronous job finishes. It wasn't clear from your question if this is exactly the behaviour you want but it gives you the idea. It will print out value of decremented variable, but user can enter text, and it will print that out once user presses enter.
#include <iostream>
#include <thread>
#include <future>
#include <time.h>
int main() {
// Enable standard literals as 2s and ""s.
using namespace std::literals;
// Execute lambda asyncronously (waiting for user input)
auto f = std::async(std::launch::async, [] {
auto s = ""s;
if (std::cin >> s) return s;
});
// Continue execution in main thread, run countdown and timer:
int countdown = 20;
int countdownPrev = 0;
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point end;
double elapsed;
while((f.wait_for(5ms) != std::future_status::ready) && countdown >= 0) {
end = std::chrono::steady_clock::now();
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
countdown = 20 - (int) (elapsed/1000);
if (countdown != countdownPrev) {
std::cout << "Counter now: " << std::fixed << countdown << std::endl;
countdownPrev = countdown;
}
}
if (countdown == -1) {
std::cout << "Countdown elapsed" << std::endl;
return -1;
} else {
std::cout << "Input was: " << f.get() << std::endl;
return 0;
}
}
P.S. to get this to work on my compiler I have to compile it with g++ -pthread -std=c++14 file_name.cpp to correctly link the threading library and allow use of c++14 features.
Related
Is it possible to set timeout for std::cin?
For example, std::cin doesn't receive any data during 10 seconds - it throws an exception or returns an error.
Edited:
And what about timer from Boost library? As far as I know, it is portable library. Is it possible to ask timer of Boost library to throw exceptions after predefined period of time? I guess it can solve this problem.
It isn't possible to set a time out for std::cin in a portable way. Even when resorting to non-portable techniques, it isn't entirely trivial to do so: you will need to replace std::cin's stream buffer.
On a UNIX system I would replace the default stream buffer used by std::cin by a custom one which uses file descriptor 0 to read the input. To actually read the input I would use poll() to detect presence of input and set a timeout on this function. Depending on the result of poll() I would either read the available input or fail. To possibly cope with typed characters which aren't forwarded to the file descriptor, yet, it may be reasonable to also turn off the buffering done until a newline is entered.
When using multiple threads you can create a portable filtering stream buffer which uses on thread to read the actual data and another thread to use a timed condition variable waiting either for the first thread to signal that it received data or for the time out to expire. Note that you need to guard against spurious wake-ups to make sure that the timeout is indeed reached when there is no input. This would avoid having to tinker with the actual way data is read from std::cin although it still replaces the stream buffer used by std::cin to make the functionality accessible via this name.
I just figured out how to do that, polling the std::cin file descriptor.
poll function returns 0 if timeout occurs and no event happened, 1 if something happened, and -1 if error happened.
#include <iostream>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
bool stop = false;
void intHandler(int dummy)
{
stop = true;
}
std::string readStdIn()
{
struct pollfd pfd = { STDIN_FILENO, POLLIN, 0 };
std::string line;
int ret = 0;
while(ret == 0)
{
ret = poll(&pfd, 1, 1000); // timeout of 1000ms
if(ret == 1) // there is something to read
{
std::getline(std::cin, line);
}
else if(ret == -1)
{
std::cout << "Error: " << strerror(errno) << std::endl;
}
}
return line;
}
int main(int argc, char * argv[])
{
signal(SIGINT, intHandler);
signal(SIGKILL, intHandler);
while(!stop)
{
std::string line = readStdIn();
std::cout << "Read: " << line << std::endl;
}
std::cout << "gracefully shutdown" << std::endl;
}
There was a good answer posted here but the author removed it. It's a solution that worked well for me in the application I was developing. This is the essence of what the person wrote:
// compile: g++ -pthread thisfile.cpp
#include <iostream>
#include <thread>
int main() {
int x;
bool inputReceived = false;
time_t startTime = time(NULL);
time_t waitTime = 10;
std::cout << "Enter a number within " << waitTime << " seconds\n";
// spawn a concurrent thread that waits for input from std::cin
std::thread t1([&]() {
std::cin >> x;
inputReceived = true;
});
t1.detach();
// check the inputReceived flag once every 50ms for 10 seconds
while (time(NULL) < startTime + waitTime && !inputReceived) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
if (inputReceived) {
std::cout << "x = " << x << "\n";
return EXIT_SUCCESS;
}
std::cout << "timeout\n";
// TODO: find a way to kill the thread
return EXIT_FAILURE;
}
Be aware that the thread continues running after the timeout occurs, but it will terminate when the whole program terminates. If this is all you need then you don't need to worry about it.
However, there is no simple way to kill a detached thread. A solution would be to close the input stream, but that's not easy or desirable to do with std::cin. If you're lucky then you're going to use this with an easily closeable stream instead of std::cin. Closing the stream will cause input statement to fail and the the thread will probably just exit with an internal exception, but at least the thread will terminate.
At this question, I asked how to unblock a grpc::CompletionQueue::Next() that is waiting on a grpc::Channel::NotifyOnStateChange(..., gpr_inf_future(GPR_CLOCK_MONOTONIC), ...).
That question, specifically, is still unanswered, but I am trying a workaround, where the CompletionQueue is instead waiting on a grpc::Channel::NotifyOnStateChange() with a non-infinite deadline:
// main.cpp
#include <chrono>
#include <iostream>
#include <memory>
#include <thread>
#include <grpcpp/grpcpp.h>
#include <unistd.h>
using namespace std;
using namespace grpc;
void threadFunc(shared_ptr<Channel> ch, CompletionQueue* cq) {
void* tag = NULL;
bool ok = false;
int i = 1;
grpc_connectivity_state state = ch->GetState(false);
std::chrono::time_point<std::chrono::system_clock> now =
std::chrono::system_clock::now();
std::chrono::time_point<std::chrono::system_clock> deadline =
now + std::chrono::seconds(2);
cout << "state " << i++ << " = " << (int)state << endl;
ch->NotifyOnStateChange(state,
//gpr_inf_future(GPR_CLOCK_MONOTONIC),
deadline,
cq,
(void*)1);
while (cq->Next(&tag, &ok)) {
state = ch->GetState(false);
cout << "state " << i++ << " = " << (int)state << endl;
now = std::chrono::system_clock::now();
deadline = now + std::chrono::seconds(2);
ch->NotifyOnStateChange(state,
//gpr_inf_future(GPR_CLOCK_MONOTONIC),
deadline,
cq,
(void*)1);
}
cout << "thread end" << endl;
}
int main(int argc, char* argv[]) {
ChannelArguments channel_args;
CompletionQueue cq;
channel_args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0);
channel_args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, 2000);
channel_args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, 2000);
channel_args.SetInt(GRPC_ARG_HTTP2_BDP_PROBE, 0);
channel_args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, 60000);
channel_args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 30000);
channel_args.SetInt(GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS,
60000);
{
shared_ptr<Channel> ch(CreateCustomChannel("my_grpc_server:50051",
InsecureChannelCredentials(),
channel_args));
std::thread my_thread(&threadFunc, ch, &cq);
cout << "sleeping" << endl;
sleep(5);
cout << "slept" << endl;
cq.Shutdown();
cout << "shut down cq" << endl;
my_thread.join();
}
}
Output of the running executable:
$ ./a.out
sleeping
state 1 = 0
state 2 = 0
state 3 = 0
slept
shut down cq
state 4 = 0
E1012 15:29:07.677225824 54 channel_connectivity.cc:234] assertion failed: grpc_cq_begin_op(cq, tag)
Aborted (core dumped)
This version periodically unblocks, as expected, but why does it assert?
My question is ultimately: how do you cleanly exit from a loop/thread that is waiting on a grpc::CompletionQueue that is waiting on a grpc::Channel::NotifyOnStateChange() ?
My experience has been that with an infinite deadline, it's impossible to unblock grpc::CompletionQueue::Next(), and with a non-infinite deadline, shutting down the grpc::CompletionQueue results in an assert, which is presumably a non-clean exit.
The documentation for CompletionQueue::Shutdown()`](https://grpc.github.io/grpc/cpp/classgrpc_1_1_completion_queue.html#a40efddadd9073386fbcb4f46e8325670) says:
Also note that applications must ensure that no work is enqueued on this completion queue after this method is called.
In other words, once you shut down the CQ, it is illegal to call NotifyOnStateChange() again, because that is enqueing new work.
In this case, what you should expect to see after you call CompletionQueue::Shutdown() is that the already-invoked call to CompletionQueue::Next() will return the already-requested NotifyOnStateChange() completion, and the next call to CompletionQueue::Next() will return false, thus indicating that the CQ is shut down. However, your code is not making a call to Next() to see if the CQ is shut down before it calls NotifyOnStateChange() again to request another state change notification, so that is happening after the CQ is shut down, which is why you're seeing this assertion.
In general, the right way to use a CQ is to have a separate, dedicated set of threads that always call Next() in a loop but do not themselves start any new work on the CQs. Starting new work on the CQs should be done in separate thread(s) and should not be done after the CQ is shut down.
I hope this information is helpful.
I'm trying to write a kind of thread pool in C++. The code works fine in OSX, but under Linux I'm experiencing a strange behavior.
After a bit of debugging, I found the problem is due to a call to std::condition_variable::wait_until that I must be doing in a wrong way.
With the code below I expect the loop to be looped once every three seconds:
#include <mutex>
#include <chrono>
#include <iostream>
#include <memory>
#include <condition_variable>
#include <thread>
using namespace std;
typedef std::chrono::steady_clock my_clock;
typedef std::chrono::duration<float, std::ratio<1> > seconds_duration;
typedef std::chrono::time_point<my_clock, seconds_duration> timepoint;
timepoint my_begin = my_clock::now();
float timepointToFloat(timepoint time) {
return time.time_since_epoch().count() - my_begin.time_since_epoch().count();
}
void printNow(std::string mess) {
timepoint now = my_clock::now();
cout << timepointToFloat(now) << " " << mess << endl;;
};
void printNow(std::string mess, timepoint time ) {
timepoint now = my_clock::now();
cout << timepointToFloat(now) << " " << mess << " " << timepointToFloat(time) << endl;;
};
int main() {
mutex _global_mutex;
condition_variable _awake_global_execution;
auto check_predicate = [](){
cout << "predicate called" << endl;
return false;
};
while (true) {
{ // Expected to loop every three seconds
unique_lock<mutex> lock(_global_mutex);
timepoint planned_awake = my_clock::now() + seconds_duration(3);
printNow("wait until", planned_awake);
_awake_global_execution.wait_until(lock, planned_awake, check_predicate);
}
printNow("finish wait, looping");
}
return 0;
}
However, sometimes I get as output:
<X> wait until <X+3>
predicate called
(...hangs here for a long time)
(where X is a number), so it seems the timeout is not scheduled after three seconds. Sometimes instead I get:
<X> wait until <X+3>
predicate called
predicate called
<X> finish wait, looping
<X> wait until <X+3> (another loop)
predicate called
predicate called
<X> finish wait, looping
(...continue looping without waiting)
so it seems the timeout is scheduled after a small fraction of seconds. I think I'm messing up something with the timeout timepoint, but I cannot figure out what I'm doing wrong.
If it may be relevant, this code works fine in OSX, while in Linux (Ubuntu 16.04, gcc 5.4, compiled with "g++ main.cc -std=c++11 -pthread") I'm experiencing the strange behavior.
How can I get it work?
Try to cast your timeout to your clock's duration:
auto planned_awake = my_clock::now() +
std::chrono::duration_cast<my_clock::duration>(seconds_duration(3));
I want to add a delay so that one line will run and then after a short delay the second one will run. I'm fairly new to C++ so I'm not sure how I would do this whatsoever. So ideally, in the code below it would print "Loading..." and wait at least 1-2 seconds and then print "Loading..." again. Currently it prints both instantaneously instead of waiting.
cout << "Loading..." << endl;
// The delay would be between these two lines.
cout << "Loading..." << endl;
in c++ 11 you can use this thread and crono to do it:
#include <chrono>
#include <thread>
...
using namespace std::chrono_literals;
...
std::this_thread::sleep_for(2s);
to simulate a 'work-in-progress report', you might consider:
// start thread to do some work
m_thread = std::thread( work, std::ref(*this));
// work-in-progress report
std::cout << "\n\n ... " << std::flush;
for (int i=0; i<10; ++i) // for 10 seconds
{
std::this_thread::sleep_for(1s); //
std::cout << (9-i) << '_' << std::flush; // count-down
}
m_work = false; // command thread to end
m_thread.join(); // wait for it to end
With output:
... 9_8_7_6_5_4_3_2_1_0_
work abandoned after 10,175,240 us
Overview: The method 'work' did not 'finish', but received the command to abandon operation and exit at timeout. (a successful test)
The code uses chrono and chrono_literals.
In windons OS
#include <windows.h>
Sleep( sometime_in_millisecs ); // note uppercase S
In Unix base OS
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
#include <unistd.h>
int usleep(useconds_t usec); // Note usleep - suspend execution for microsecond intervals
You want the sleep(unsigned int seconds) function from unistd.h. Call this function between the cout statements.
The thing is i want to use c++ library which runs different threads simultaneously without having other threads to wait until the preceding thread is complete and their functionality within each thread is run simultaneuslly,I am talking about the code which is to be run in the thread;the sample code is shown below.
while(condition is true<it is infinite loop >){
running sleep here with random time
sleep(random time(sec))
rest of the code is here
}
This infinite while loop is run in each thread. I want to run this while loop in each thread to be run simultaneously without being stuck at the first thread to be completed. In other words all the infinite while loop(in each thread context) is to be run simultaneously. How do I achieve that? If you can please share some sample code actually I have used future with async but I get the same behavior as normal <thread> using join().
The issue you are encountering is because of the rather silly definition of std::async (in my opinion) that it doesn't have to execute your code asynchronously, but can instead run it when you attempt to get from its std::future return value.
No matter. If you set the first parameter of your call to std::launch::async you force it to run asynchronously. You can then save the future in a container, and if you retire futures from this container regularly, you can run as many threads as the system will let you.
Here's an example:
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <vector>
#include <mutex>
using future_store = std::vector<std::future<void>>;
void retireCompletedThreads(future_store &threadList)
{
for (auto i = threadList.begin(); i != threadList.end(); /* ++i */)
{
if (i->wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
i->get();
i = threadList.erase(i);
}
else
{
++i;
}
}
}
void waitForAllThreads(future_store &threadList)
{
for (auto& f : threadList)
{
f.get();
}
}
std::mutex coutMutex;
int main(int argc, char* argv[])
{
future_store threadList;
// No infinite loop here, but you can if you want.
// You do need to limit the number of threads you create in some way though,
// for example, only create new threads if threadList.size() < 20.
for (auto i = 0; i < 20; ++i)
{
auto f = std::async(std::launch::async,
[i]() {
{
std::lock_guard<std::mutex> l(coutMutex);
std::cout << "Thread " << i << " started" << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> l(coutMutex);
std::cout << "Thread " << i << " completed" << std::endl;
}
});
threadList.push_back(std::move(f));
// Existing threads need to be checked for completion every so often
retireCompletedThreads(threadList);
}
waitForAllThreads(threadList);
}