void sendCommand(float t,char* cmd)
{
std::clock_t endwait;
double endwait = clock () + t * CLOCKS_PER_SEC ;
while (clock() < endwait) {}
if( clock() < endwait)
printf("\nThe waited command is =%s",cmd);
}
void Main()
{
sendCommand(3.0,"Command1");
sendCommand(2.0,"Command2");
printf("\nThe first value")
return 0;
}
i want to delay a function but my application should keep on running.
In the above code i want The first value to be printed first.
than i want Command2 to be printed and Command1 should be the last to be printed.
I prefer std::async for this.
#include <chrono>
#include <thread>
#include <future>
#include <iostream>
void sendCommand(std::chrono::seconds delay, std::string cmd)
{
std::this_thread::sleep_for( delay );
std::cout << "\nThe waited command is =" << cmd;
}
int main()
{
auto s1 = std::async(std::launch::async, sendCommand, std::chrono::seconds(3),"Command1");
auto s2 = std::async(std::launch::async, sendCommand, std::chrono::seconds(2),"Command2");
std::cout << "\nThe first value" << std::flush;
s1.wait();
s2.wait();
return 0;
}
However, for a real design, I would create a scheduler (or preferably use an existing one) which manages a priority queue sorted by the delay time. Spawning a new thread for every command will quickly become a problem. Since you flagged the question for MS VIsual C++, take a look the PPL which implements task-based parallelism.
And as it a C++ question, I would stay away from the C stuff and not use printf, CLOCK_PER_SEC, char*, clock etc. You will quickly get into problems even with this simple example when you start using strings instead of the "Command1" literals. std::string will help you here.
I think you need threads. You can do it like this:
#include <thread>
#include <chrono>
#include <iostream>
void sendCommand(float t, char const* cmd)
{
std::this_thread::sleep_for(std::chrono::milliseconds(int(t * 1000)));
std::cout << "\nThe waited command is = " << cmd << '\n';
}
int main()
{
// each function call on a new thread
std::thread t1(sendCommand, 3.0, "Command1");
std::thread t2(sendCommand, 2.0, "Command2");
// join the threads so we don't exit before they finish.
t1.join();
t2.join();
}
You can do it in many ways depending upon your actual logic.
Examles;:
1.you can you a global flag variable and check its state , when third print will complete you can set flag to 1,so next call will execute.
2.you can use a STACK .push all the function pointers in a STACK . and after that pop and execute.
3.MultiThreading. You can use it with proper synchronized way, but it will be complex. It depends upon your requirement.
Thanks !!!
boost::asio is nice because it doesn't require the overhead of multiple threads.
#include <iostream>
#include <boost/asio.hpp>
using namespace std;
int main()
{
boost::asio::io_service svc;
boost::asio::deadline_timer t0{svc};
boost::asio::deadline_timer t1{svc};
boost::asio::deadline_timer t2{svc};
t0.expires_from_now(boost::posix_time::seconds{1});
t1.expires_from_now(boost::posix_time::seconds{2});
t2.expires_from_now(boost::posix_time::seconds{3});
t2.async_wait([] (const boost::system::error_code& ec) { if(!ec) std::cout << "Greetings from t2!\n";});
t1.async_wait([] (const boost::system::error_code& ec) { if(!ec) std::cout << "Greetings from t1!\n";});
t0.async_wait([] (const boost::system::error_code& ec) { if(!ec) std::cout << "Greetings from t0!\n";});
svc.post([] () { std::cout << "I'm number one!\n";});
svc.run();
return 0;
}
Gives the output:
I'm number one!
Greetings from t0!
Greetings from t1!
Greetings from t2!
Related
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:
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);
}
So I was experimenting with the deadline_timer class and wrote the code below to see if I could have on deadline_timer with multiple async_wait operations that would execute at different times.
Below I create a deadline timer in the main function all the way at the bottom and initially set it to expire after 3 seconds. Then I call an async_wait operation and pass the first print function as the handler. I then use the expires_from_now operation to set the time of expiration for what I intended to only affect the second async_wait call which has print2 as a handler. The output from running this is below the code.
This is test1.cpp
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind.hpp>
#include <time.h>
#include <sys/time.h>
double get_wall_time(){
struct timeval time;
if (gettimeofday(&time,NULL)){
// Handle error
return 0;
}
return (double)time.tv_sec + (double)time.tv_usec * .000001;
}
void print(double start, const boost::system::error_code& /*e*/)
{
std::cout << "Hello, world!" << std::endl;
std::cout << get_wall_time() - start << std::endl;
}
void print2(double start, const boost::system::error_code& /*e*/)
{
std::cout << "SECOND Hello, world!" << std::endl;
std::cout << get_wall_time() - start << std::endl;
}
int main(int argc, char* argv[])
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3));
auto start = get_wall_time();
timer.async_wait(boost::bind(print, start, boost::asio::placeholders::error));
timer.expires_from_now(boost::posix_time::seconds(20));
timer.async_wait(boost::bind(print2, start, boost::asio::placeholders::error));
io.run();
return 0;
}
Here is the output
Hello, world!
0.000774145
SECOND Hello, world!
20.0085
This is the output after commenting out the second async_wait with the expiration modification.
Hello, world!
3.00079
As you can see the first handler executes instantly when I intended for it to execute after 3 seconds. The second handler correctly executes after 20 seconds. Is there any way I could get the behavior I intended with a deadline_timer without having to create a bunch of them?
A timer must have only one outstanding async_wait at a time. IIRC, issuing another implicitly cancels the first one (which will fire it's handler with an error code) as if you called cancel() followed by async_wait().
If you want to respond to 2 timer events, you have 2 choices. Either have 2 timers, or set the timeout and issue the second async_wait in the handler of the first.
As I understand it, I should be able to use a boost:asio asynchronous timer to trigger a callback every n milliseconds whilst my program is doing something else without needing threads. Is that assumption correct ?
I put together the following test program which just prints the handler messages and never prints the rand() values. What I want is to see all the floating point numbers scroll down the screen, then every 250ms a handler message should appear in amongst them.
Here is the code :
#include <iostream>
#include <vector>
#include <cstdlib>
#include <boost/asio.hpp>
#include <boost/date_time.hpp>
#include <boost/thread.hpp>
boost::asio::io_service io_service;
boost::posix_time::time_duration interval(boost::posix_time::milliseconds(250));
boost::asio::deadline_timer timer(io_service,interval);
void handler(const boost::system::error_code& error);
void timer_init() {
timer.expires_at(timer.expires_at()+interval);
timer.async_wait(handler);
}
void handler(const boost::system::error_code& error) {
static long count=0;
std::cout << "in handler " << count++ << std::endl;
std::cout.flush();
timer_init();
}
int main(int argc, char **argv) {
timer.async_wait(handler);
io_service.run();
std::vector<double> vec;
for (long i=0; i<1000000000; i++) {
double x=std::rand();
std::cout << x << std::endl;
std::cout.flush();
vec.push_back(x);
}
return 0;
}
This:
io_service.run();
Is a blocking call. It's true that you can have multiple things happening asynchronously in one thread using ASIO, but you cannot have ASIO running in the same thread as code which is not integrated with ASIO. This is a classic event-driven model, where all the work gets done in response to some readiness notification (timers, in your case).
Try moving your vector/rand code to a function and passing that function to io_service::post(), which will then run that code within the context of its run() method. Then when you invoke run(), both things will happen (though not truly concurrently, as that would require threads).
As John Zwinck mentioned, io_service::run() blocks - it's a main asio loop that dispatches completion handlers. However, instead of calling run, you can "manually" process the io_service queue by interleaving io_service::poll_one with your loop:
for (long i=0; i<1000000000; i++) {
double x=std::rand();
std::cout << x << std::endl;
std::cout.flush();
vec.push_back(x);
io_service.poll_one();
}
I tried using the boost deadline_timer in this simple test application, but had some trouble. The goal is for the timer to trigger every 45 milliseconds using the expires_at() member function of the deadline_timer. (I need an absolute time, so I'm not considering expires_from_now(). I am also not concerned about drift at the moment). When I run the program, wait() does not wait for 45 ms! Yet, no errors are reported. Am I using the library incorrectly somehow?
Sample program:
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
using namespace std;
int main()
{
boost::asio::io_service Service;
boost::shared_ptr<boost::thread> Thread;
boost::asio::io_service::work RunForever(Service);
Thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &Service)));
boost::shared_ptr<boost::asio::deadline_timer> Timer(new boost::asio::deadline_timer(Service));
while(1)
{
boost::posix_time::time_duration Duration;
Duration = boost::posix_time::microseconds(45000);
boost::posix_time::ptime Start = boost::posix_time::microsec_clock::local_time();
boost::posix_time::ptime Deadline = Start + Duration;
boost::system::error_code Error;
size_t Result = Timer->expires_at(Deadline, Error);
cout << Result << ' ' << Error << ' ';
Timer->wait(Error);
cout << Error << ' ';
boost::posix_time::ptime End = boost::posix_time::microsec_clock::local_time();
(cout << "Duration = " << (End - Start).total_milliseconds() << " milliseconds" << endl).flush();
}
return 0;
}
You are mixing local time with system time. The time that asio is comparing your local time to is most likely some number of hours after the time that you want your deadline set to so wait returns immediately (depending on where you live; this same code could wait for several hours as well). To avoid this point of confusion, absolute times should be derived from asio::time_traits.
#include <boost/asio.hpp>
#include <boost/asio/time_traits.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
using namespace std;
typedef boost::asio::time_traits<boost::posix_time::ptime> time_traits_t;
int main() {
boost::asio::io_service Service;
boost::shared_ptr<boost::thread> Thread;
boost::asio::io_service::work RunForever(Service);
Thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &Service)));
boost::shared_ptr<boost::asio::deadline_timer> Timer(new boost::asio::deadline_timer(Service));
while(1)
{
boost::posix_time::time_duration Duration;
Duration = boost::posix_time::microseconds(45000);
boost::posix_time::ptime Start = time_traits_t::now();
boost::posix_time::ptime Deadline = Start + Duration;
boost::system::error_code Error;
size_t Result = Timer->expires_at(Deadline, Error);
cout << Result << ' ' << Error << ' ';
Timer->wait(Error);
cout << Error << ' ';
boost::posix_time::ptime End = boost::posix_time::microsec_clock::local_time();
(cout << "Duration = " << (End - Start).total_milliseconds() << " milliseconds" << endl).flush();
}
return 0;
}
That should work out for you in this case.
You are mixing asynchronous methods io_service::run with synchronous methods deadline_timer::wait. This will not work. Either use deadline_timer::async_wait with io_service::run, or skip the io_service::run and just use deadline_timer::wait. You also don't need a thread to invoke io_service:run if you go the asynchronous route, one thread will do just fine. Both concepts are explained in detail in the Basic Skills section of the Asio tutorial.
void print(const boost::system::error_code& /*e*/)
{
std::cout << "Hello, world!\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
t.async_wait(print);
io.run();
return 0;
}
Note you will need to give some work for your io_service to service prior to invoking run(). In this example, async_wait is that work.
Potentially unrelated: 45ms is quite a small delta. In my experience the smallest time for any handler to make it through the Asio epoll reactor queue is around 30 ms, this can be considerably longer at higher loads. Though it all largely depends on your application.