I want to design a timer in c++, to execute my function after a fixed time.
the code likes like:
#include <thread>
typedef void (*callback)();
class timer {
public:
void start(int sec, callback f) {
std::thread t([&sec, &f]() {sleep(sec); f();});
}
};
void test () {
printf("here called\n");
}
int main() {
timer t;
t.start(3, test);
while (1);
}
but when i run this code, i got:
terminate called without an active exception
[1] 3168208 abort (core dumped) ./a.out
can you help on this? and, any suggestions for a more flexible timer design?
You created a std::thread and destructed it without detaching it.
std::thread t([&sec, &f]() {sleep(sec);
Either call join to wait on it, or call detach.
Note also the capture by reference issue in your comments.
There are a few problems with your code that need to be addressed:
After spawning a std::thread you need to synchronize it using std::thread::join().
Remove the reference capture from the sec parameter in order to prevent dangling of references by the end of the scope of start().
sleep() is platform-dependent, so your code will only work for certain platforms that support it. Instead use, std::this_thread::sleep_for(std::chrono::seconds(sec));
#include <thread>
#include <chrono> // For std::chrono
#include <cstdio> // For printf
typedef void (*callback)();
class timer {
// Bring the thread object outside the function and make it an instance variable of the class
std::thread t;
public:
// Spawns a thread
void start(int const sec, callback&& f) {
if (t.joinable()) // If the object already has a thread attached to it, call 'join()' on it
t.join();
/* Capture 'sec' by value as it is a local variable, consequently, capture
'f' by reference as it is a function and its lifetime is throughout the whole
program */
t = std::thread([sec, &f]() {
std::this_thread::sleep_for(std::chrono::seconds(sec));
f();
});
}
// After the class gets destroyed, the thread is synchronized
~timer() {
t.join();
}
};
void test () {
printf("here called\n");
}
int main() {
timer t;
t.start(3, test);
}
Related
I never did any C++ or multithreading before and need help about something.
Let's suppose I have this in my hpp file.
Class Test{
public:
struct type_something_to_kill_the_foo_thread something_to_kill_the_foo_thread;// I don't know what
void foo(stuff stuff){
while(true) does_stuff(stuff);
}
void thread_foo(stuff stuff){
std::thread th = (&Test::foo, this, stuff);
something_to_kill_the_foo_thread = th; // or th.getid() any mechanism so that I can invoke a function to destroy the thread
sleep(MAX_INT);
}
}
And I have this in my main.
Test t = Test();
t.thread_foo("random stuff1");
t.thread_foo("random stuff2");
...
How can I parallelize these two calls without using a thread in my main so my main keeps going ? Where do I put my join() if I need one and how to destroy the first thread ?
I have been having a hard time with online tutorials as they always call std::thread in the main().
That's how you make a thread:
#include <thread>
int main() {
Test t = Test();
std::thread(t.thread_foo, "random stuff1").detach()
std::thread(t.thread_foo, "random stuff2").detach()
// Works in parallel
}
Is it possible I can invoke a function on a specific thread given the thread ID? I am currently on a different thread.
You need cooperation from the target thread; for instance, the target thread has to execute a loop at the top of which it waits on some sort of message box. Through that message box you give it a message that contains the function to be called and the arguments to use. Through the same mechanism, the function can produce a reply containing the result of the call.
But you can't just make a random thread that is running arbitrary code call your function. Although, never say never. There are tricks like, for instance, asynchronous POSIX signals and such: send a signal to a thread, which inspects some datum that tells it to call a function. That is confounded by the limitations as to what can be safely done out of a signal handler.
In a debugger, you can stop all the threads, then "switch" to a particular one and evaluate expressions in its context, including function calls. That is also an approach that would be inadvisable to integrate into production code; you have no idea what state a stopped thread is in to be able to safely and reliably do anything in that thread.
One possible solution is to make the worker threads execute based on tasks (functions),i.e you use a container to store functions you'd like the worker thread to execution, and the work thread's job is to execute functions in the container.
Here's an example, hope it helps.
#include <iostream>
#include <list>
#include <functional>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
using namespace std;
void foo() {
cout << "foo() is called" << endl;
}
template<typename T>
class TaskQueue {
public:
void enqueue(T&& task) {
unique_lock<mutex> l(m);
tasks.push_back(move(task));
cv.notify_one();
}
bool empty() { unique_lock<mutex> l(m); return tasks.empty(); }
void setStop() { stop = true; unique_lock<mutex> l(m); cv.notify_one(); }
void run() {
T t;
while (!stop) {
{
unique_lock<mutex> l(m);
cv.wait(l, [&] {return !tasks.empty() || stop;});
if (!tasks.empty()) {
t = move(tasks.front());
tasks.pop_front();
}
else
return;
}
t();
}
}
private:
atomic<bool> stop = false;
mutex m;
condition_variable cv;
list<T> tasks;
};
int main() {
TaskQueue<function<void(void)>> taskq;
thread t(&TaskQueue<function<void(void)>>::run, &taskq);
taskq.enqueue(foo);
taskq.enqueue(foo);
taskq.enqueue(foo);
while (!taskq.empty()) {}
taskq.setStop();
t.join();
}
following code is a scoped thread example in c++ concurrency in action. but i has a question when run this example in xcode5.1, because the Scoped_thread t is join in its destructor function, destructor of t is run in the end of thread main()? so no matter how long I has the main() thread sleep, the main's output is before the t's output, but the answer is not? anyone can help me explain this?
#include <iostream>
#include <algorithm>
#include <thread>
#include <chrono>
using namespace std;
struct Scoped_thread
{
std::thread sthread;
Scoped_thread(std::thread tmp):sthread(std::move(tmp))
{
if (!sthread.joinable())
{
cout<<"error on contructor a scoped thread"<<endl;
}
}
~Scoped_thread()
{
sthread.join();
}
Scoped_thread(Scoped_thread& tmp) = delete;
Scoped_thread& operator =(const Scoped_thread& tmp) = delete;
};
void hello_scoped_thread()
{
cout<<"this is scoped thread output"<<endl;
}
int main()
{
Scoped_thread t((std::thread(hello_scoped_thread)));
//std::this_thread::sleep_for(std::chrono::seconds(10));
cout<<"this is in main thread"<<endl;
return 0;
}
edit plus:i want to know when the main thread known t thread is joined, when main do destruct the t? / during compiler parse the code or sometime like this?
The thread is running asynchronously, so there should be not too much concern about the order of actions between the thread and main. The actions are normally done as fast as possible, so when 1 thread waits, the others can just continue.
The scoped thread class just takes care that the main thread waits until the new thread finishes at the end of the scope, which is the end of the main() function, by joining.
After using threads for a while, I got into a situation where I needed a thread to run forever until a a function (or any sort of event) was called. To do this I created a bool value to control a while loop inside the function that was executed by the thread, but I quickly noticed that external variables are not updated after a thread starts running, causing the thread to never stop when it was asked to.
Heres some simple code to represent the issue:
#include <cstdio>
#include <thread>
#include <chrono>
class A {
public:
A();
void startThread();
void endThread();
private:
void threadCall();
bool active;
};
int main() {
A threadThing;
threadThing.startThread();
printf("[M] Thread Created\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
threadThing.endThread();
printf("[M] Thread Killed\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
return 0;
}
A::A() {
active = false;
}
void A::startThread() {
active = true;
std::thread AThread(&A::threadCall, *this);
AThread.detach();
}
void A::endThread() {
active = false;
}
void A::threadCall() {
printf("[T] Thread Started\n");
while (active) {
std::this_thread::sleep_for(std::chrono::seconds(2));
}
printf("[T] Thread Ended\n");
}
The expected result of this would be that the main function starts the thread, the thread says it started, then 4 seconds later the thread is killed and the thread says it ended, when in reality the thread never says it ends. Is there a way to let the thread access the 'active' variable, or is my approach to this problem incorrect altogether? (Side note, I did try to figure this out on my own but only got stuff like local thread storage which seems like its only for storage inside of threads, not access to the outside but I could be wrong)
The problem is with the constructor of std::thread, it copies/moves by default.
std::thread AThread(&A::threadCall, *this);
this copies the object into the new thread, so checking the active variable in the new object has no effect.
you can remove the *
std::thread AThread(&A::threadCall, this);
you pass the object pointer into the new thread, it will call like the method like this(*this).threadCall().
Edit: as the comments say, this is not guarantee to be thread safe, you need to use std::atomic<bool> to be safe.
What you need to do is pass an A class pointer as an argument to your function that is your thread.
void A::startThread()
{
active = true;
std::thread AThread(threadCall, this);
AThread.detach();
}
void A::threadCall(A *aClass)
{
printf("[T] Thread Started\n");
while (aClass->active)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
}
printf("[T] Thread Ended\n");
}
In my project every class object has its own thread with infinite cycle (while(1)) inside, in which particular object functions are performed. And I'm trying to change this so that every object would perform its functions asynchronously with timers.
Basically this is how it works with thread with infinite loop:
class obj
{
public:
obj();
~obj();
//custom functions and variables
int x;
int obj_action;
move();
wait();
}
obj()
{
obj_action=1;
//when constructing object, make its thread with infinite while cycle
boost::thread make_thread(boost::bind(&obj::obj_engine,this));
}
void obj::obj_engine()
{
while(true)
{
if (obj_action==1){move();}
else if (obj_action==2){wait();}
Sleep(1);
}
}
void obj::move()
{
x++;
obj_action==2;
}
void obj::wait()
{
Sleep(5000);
obj_action==1;
}
This example shows, the obj class, which has constructor , destructor, couple of variables and couple of functions.
When constructing an object (obj()), thread is made. Thread contains a function "obj_engine" , which has infinite loop (while(true)). In the loop there is two functions:
1. wait() - makes a thread sleep for 5 seconds.
2. walk() - simply x+1
those 2 functions switches each other after its end by defining obj_action.
Now I want to change this to, when the constructing and object , asynchronously move() function would be performed, and after move() function, asynchronously wait() function would be performed, and vice verse. So I wouldn't need to use any threads.
I hoping for result like this:
//constructing
obj()
{
asynchronous(walk());
}
walk()
{
x++
asynchronous(wait());
}
wait()
{
Sleep(5000);
asynchronous(walk());
}
I heard you can do this, with boost::asio timers , but I really don't know how.
I would be very grateful if someone would show me how.
Here you go:
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind.hpp>
#include <iostream>
class obj {
public:
obj() : x_(0), t_(io_service_, boost::posix_time::seconds(5)) {
t_.async_wait(boost::bind(&obj::move, this));
io_service_.run();
}
void move() {
x_++;
std::cout << x_ << std::endl;
t_.expires_at(t_.expires_at() + boost::posix_time::seconds(5));
t_.async_wait(boost::bind(&obj::move, this));
}
private:
int x_;
boost::asio::io_service io_service_;
boost::asio::deadline_timer t_;
};
int main(int, char**) {
obj a;
while(true);
}
Basically everything you need is covered by the asio tutorial: this tutorial shows you how to use an asynchronous timer, and this tutorial shows you how to reset your timer.
Update:
Please use the above source code instead of my initial one - due to the repetitive calls of io_service_.run(), each move call would be called in another thread and after some time your application would crash because of it. The above code fixes this problem, and gets rid of the wait function by doing so.
Borrowing the example from nijansen, I've whipped together something that should be more similar to what you want (I think).
The key here is the io_service should be shared between all object's scheduling on it. Usually there is one io_service per thread, but more intricate schemes can be used as well. io_service::run runs for as long as there is work scheduled on the io_service (pending timeout or waiting on a socket). When no more work is scheduled, it simply returns.
You might be interested in io_service::post as a way to send messages between your "active objects" (which works even if they are running under different io_services and different threads). You may want to look at boost::bind and possibly boost::signals.
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind.hpp>
#include <iostream>
namespace asio = boost::asio;
class obj {
public:
obj(asio::io_service& ioSvc)
: x_(0), t_(ioSvc)
{
schedule_in(5);
}
void schedule_in(int seconds) {
t_.expires_from_now(boost::posix_time::seconds(3));
t_.async_wait(boost::bind(&obj::move, this));
}
void move() {
x_++;
std::cout << x_ << std::endl;
schedule_in(5);
}
private:
int x_;
boost::asio::deadline_timer t_;
};
int main(int, char**) {
boost::asio::io_service io_service;
obj a(io_service);
obj b(io_service);
obj c(io_service);
io_service.run();
}