I found a thread pool class and i tried with alot of combinations to call method with function inside.
Here is example of my try :
WorkerPool wp(4);
wp.run_task<Connection::On_NET1_LOGIN>(&On_NET1_LOGIN());
Here are the WorkerPool's functions :
template < typename Task >
void run_task( Task task )
{
boost::unique_lock< boost::mutex > lock( mutex_ );
// If no threads are available, then return.
if ( 0 == available_ ) return;
// Decrement count, indicating thread is no longer available.
--available_;
// Post a wrapped task into the queue.
io_service_.post( boost::bind( &WorkerPool::wrap_task, this,
boost::function< void() >( task ) ) );
}
private:
/// #brief Wrap a task so that the available count can be increased once
/// the user provided task has completed.
void wrap_task( boost::function< void() > task )
{
// Run the user supplied task.
try
{
task();
}
// Suppress all exceptions.
catch ( ... ) {}
// Task has finished, so increment count of available threads.
boost::unique_lock< boost::mutex > lock( mutex_ );
++available_;
}
What I doing wrong in calling function to that threadpool ?
Thanks.
You are trying to add the task like this:
wp.run_task<Connection::On_NET1_LOGIN>(&On_NET1_LOGIN());
It seems there are two issues with this.
You do not need to specify template parameters, as they can be inferred. Also, if you did, you should specify the type - not the name - of the function.
You want to pass the address of the function to be called, but you are trying to call the function and take the address of the result.
To solve both these issues, try the following:
wp.run_task(&Connection::On_NET1_LOGIN);
Note: Since On_NET1_LOGIN seems to be a member function of Connection, this won't work unless the function is static. If this is not the case, you need a Connection instance to call the function on and you need to send a function object which does this. This can be solved using a lambda or std::bind.
Related
I am implementing an Observer pattern in my C++ application. So far I have a base class defined as follows:
template<typename CallbackType,
typename LockType = utils::Lock<boost::mutex>,
typename StorageType = std::vector<std::shared_ptr<CallbackType>>>
class CallbackManager
{
LockType mCallbackLock { "commons::CallbackManager", __FILE__, __LINE__ };
StorageType mCallbacks;
virtual uint64_t registerCallback( const std::shared_ptr<CallbackType>& aCallbackPtr );
virtual bool unregisterCallback( uint64_t aCallbackId );
void iterateSubscribers(const std::function<void(typename StorageType::value_type&)>&);
};
One of the key requirement is to be able to perform registerCallback/unregisterCallback calls within the iterateSubscribers context (recursively).
iterateSubscribers function performs an iterative call of aFnc with every callback as an argument. aFnc might perform registerCallback/unregisterCallback call. Current implementation written as follows:
void iterateSubscribers(const std::function<void(typename StorageType::value_type&)>& aFnc)
{
decltype(mCallbacks) callbacks;
{
// BEGIN SCOPED LOCK
auto lock = mCallbackLock.getScopedLock();
boost::ignore_unused( lock ); // To supress the warning in case NoLock is used
callbacks = mCallbacks;
// END SCOPED LOCK
}
for( auto it = callbacks.begin(); it != callbacks.end(); ++it )
{
aFnc( *it );
}
}
I am performing a copy of the callbacks container which is kinda not really good from the performance point of view but resolves two issues:
mCallbacks modifications do not break a loop
new lock acquisitions will not cause a deadlock
The trade-off is acceptable for me, I will not notify newly added subscribers and will not skip notification for recently removed subscribers.
What I can't resolve in an acceptable way is:
Non-copyable container as a template parameter for StorageType will cause a compilation error in iterateSubscribers function
The one possible solution is to define such container or its value_type as a pointer, but for the reasons I cannot afford this.
I also gave a look on alternative solution - do not perform a copy, replace regular mutex with a recursive mutex and perform all calls under the lock held, but it has one problem. Once element will be added or deleted, the loop will be broken:
for( auto it = callbacks.begin(); it != callbacks.end(); ++it )
Is there any other technique/ideas to achieve desired behavior?
EDIT:
I went by the road of the refactoring. Changing legacy callback containers value_type from the copy of the callback to the shared_ptr. That allowed me to copy the container and to not rely on the TriviallyCopyable state of the underplaying value_type.
The following code starts a non-blocking timer that will launch the function myFunc after one second:
MyClass.h:
std::future<void> timer_future_;
MyClass.cpp:
timer_future_ = std::async(
std::launch::async,
[this] { QTimer::singleShot(1000,
[this] {this->myFunc();}
);
}
);
I would like to replace the lambda functions with std::functions. I have successfully replaced the second lambda as follows:
timer_future_ = std::async(
std::launch::async,
[this] { QTimer::singleShot(1000,
std::bind(&MyClass::myFunc, this)
);
}
);
How can I now replace the first lambda with another std::bind() call?
Note that the function QTimer::singleShot is from the Qt libraries; its documentation is here. Its prototype is:
void QTimer::singleShot(int msec, Functor functor)
As per this question, the definition of the Functor type can be found in QObject.h. It says:
template <class FunctorT, class R, typename... Args> class Functor { /*...*/ }
After some research, I understand that the std::bind() that will replace the first lambda must take account of the following:
QTimer::singleShot is an overloaded function, so I must use a cast to disambiguate the call to it
QTimer::singleShot is a static member function, so the pointer to it must resemble a pointer to a non-member function
I have made several unsuccessful attempts, the last of which was:
timer_future_ = std::async(
std::launch::async,
std::bind( ( void(*) (int, Functor<const std::function<void(void)>,void>) )&QTimer::singleShot,
1000,
std::bind(&MyClass::myFunc, this)
)
);
For this code, the MSVC compiler returned the error message
error: C2059: syntax error: ')'
on the third line.
Why don’t I just use the lambdas which are already working? The answer is simply that trying to use std::bind() instead is teaching me more about the various features of the C++ language and how to use them.
EDIT: Code that implements Kuba Ober's answer:
QTimer::singleShot(1000, [this] {
timer_future_ = std::async(
std::launch::async,
std::bind(&MyClass::myFunc, this)
);
});
The timer requires an event loop, and std::async will invoke it in a worker thread that doesn't have a running event loop. I question why would you ever want to do it?
If you want to run something in a worker thread after a delay, run the timer in a thread that has an event loop, and fire off the async action from that timer.
Count opening and closing brackets and add a semicolon
I'm getting into C++11 threads and have run into a problem.
I want to declare a thread variable as global and start it later.
However all the examples I've seen seem to start the thread immediately for example
thread t(doSomething);
What I want is
thread t;
and start the thread later.
What I've tried is
if(!isThreadRunning)
{
thread t(readTable);
}
but now t is block scope. So I want to declare t and then start the thread later so that t is accessible to other functions.
Thanks for any help.
std::thread's default constructor instantiates a std::thread without starting or representing any actual thread.
std::thread t;
The assignment operator moves the state of a thread object, and sets the assigned-from thread object to its default-initialized state:
t = std::thread(/* new thread code goes here */);
This first constructs a temporary thread object representing a new thread, transfers the new thread representation into the existing thread object that has a default state, and sets the temporary thread object's state to the default state that does not represent any running thread. Then the temporary thread object is destroyed, doing nothing.
Here's an example:
#include <iostream>
#include <thread>
void thread_func(const int i) {
std::cout << "hello from thread: " << i << std::endl;
}
int main() {
std::thread t;
std::cout << "t exists" << std::endl;
t = std::thread{ thread_func, 7 };
t.join();
std::cout << "done!" << std::endl;
}
As antred says in his answer, you can use a condition variable to make the thread to wait in the beginning of its routine.
Scott Meyers in his book “Effective Modern C++” (in the “Item 39: Consider void futures for one-shot event communication”) proposes to use void-future instead of lower level entities (boolean flag, conditional variable and mutex). So the problem can be solved like this:
auto thread_starter = std::promise<void>;
auto thread = std::thread([starter_future = thread_starter.get_future()]() mutable {
starter_future.wait(); //wait before starting actual work
…; //do actual work
});
…; //you can do something, thread is like “paused” here
thread_starter.set_value(); //“start” the thread (break its initial waiting)
Scott Meyers also warns about exceptions in the second … (marked by the you can do something, thread is like “paused” here comment). If thread_starter.set_value() is never called for some reasons (for example, due to exception throws in the second …), the thread will wait forever, and any attempt to join it would result in deadlock.
As both ways (condvar-based and future-based) contain hidden unsafety, and the first way (condvar-based) needs some boilerplate code, I propose to write a wrapper class around std::thread. Its interface should be similar to the one of std::thread (except that its instances should be assignable from other instances of the same class, not from std::thread), but contain additional void start() method.
Future-based thread-wrapper
class initially_suspended_thread {
std::promise<bool> starter;
std::thread impl;
public:
template<class F, class ...Args>
explicit initially_suspended_thread(F &&f, Args &&...args):
starter(),
impl([
starter_future = starter.get_future(),
routine = std::bind(std::forward<F>(f), std::forward<Args>(args)...)
]() mutable {if (starter_future.get()) routine();})
{}
void start() {starter.set_value(true);}
~initially_suspended_thread() {
try {starter.set_value(false);}
catch (const std::future_error &exc) {
if (exc.code() != std::future_errc::promise_already_satisfied) throw;
return; //already “started”, no need to do anything
}
impl.join(); //auto-join not-yet-“started” threads
}
…; //other methods, trivial
};
Condvar-based thread-wrapper
class initially_suspended_thread {
std::mutex state_mutex;
enum {INITIAL, STARTED, ABORTED} state;
std::condition_variable state_condvar;
std::thread impl;
public:
template<class F, class ...Args>
explicit initially_suspended_thread(F &&f, Args &&...args):
state_mutex(), state(INITIAL), state_condvar(),
impl([
&state_mutex = state_mutex, &state = state, &state_condvar = state_condvar,
routine = std::bind(std::forward<F>(f), std::forward<Args>(args)...)
]() {
{
std::unique_lock state_mutex_lock(state_mutex);
state_condvar.wait(
state_mutex_lock,
[&state]() {return state != INITIAL;}
);
}
if (state == STARTED) routine();
})
{}
void start() {
{
std::lock_guard state_mutex_lock(state_mutex);
state = STARTED;
}
state_condvar.notify_one();
}
~initially_suspended_thread() {
{
std::lock_guard state_mutex_lock(state_mutex);
if (state == STARTED) return; //already “started”, no need to do anything
state = ABORTED;
}
impl.join(); //auto-join not-yet-“started” threads
}
…; //other methods, trivial
};
There is no "standard" of creating a thread "suspended" which I assume is what you wanted to do with the C++ thread library. Because it is not supported on every platform that has threads, it is not there in the C++ API.
You might want to create a class with all the data it is required but not actually run your thread function. This is not the same as creating the thread but may be what you want. If so, create that, then later bind the object and its operator() or start() function or whatever to the thread.
You might want the thread id for your thread. That means you do actually need to start the thread function. However it can start by waiting on a condition variable. You then signal or broadcast to that condition variable later when you want it to continue running. Of course you can have the function check a condition after it resumes in case you might have decided to close it and not run it after all (in which case it will just return instantly).
You might want a std::thread object with no function. You can do that and attach it to a function later to run that function in a new thread.
I would give the thread a condition variable and a boolean called startRunning (initially set to false). Effectively you would start the thread immediately upon creation, but the first thing it would do is suspend itself (using the condition_variable) and then only begin processing its actual task when the condition_variable is signaled from outside (and the startRunning flag set to true).
EDIT: PSEUDO CODE:
// in your worker thread
{
lock_guard l( theMutex );
while ( ! startRunning )
{
cond_var.wait( l );
}
}
// now start processing task
// in your main thread (after creating the worker thread)
{
lock_guard l( theMutex );
startRunning = true;
cond_var.signal_one();
}
EDIT #2: In the above code, the variables theMutex, startRunning and cond_var must be accessible by both threads. Whether you achieve that by making them globals or by encapsulating them in a struct / class instance is up to you.
first declared in class m_grabber runs nothing. We assign member class object with new one with lambda function in launch_grabber method and thread with lambda runs within source class context.
class source {
...
std::thread m_grabber;
bool m_active;
...
}
bool source::launch_grabber() {
// start grabber
m_grabber = std::thread{
[&] () {
m_active = true;
while (true)
{
if(!m_active)
break;
// TODO: something in new thread
}
}
};
m_grabber.detach();
return true;
}
You could use singleton pattern. Or I would rather say antipattern.
Inside a singleton you would have std::thread object encapsulated. Upon first access to singleton your thread will be created and started.
I'm getting into C++11 threads and have run into a problem.
I want to declare a thread variable as global and start it later.
However all the examples I've seen seem to start the thread immediately for example
thread t(doSomething);
What I want is
thread t;
and start the thread later.
What I've tried is
if(!isThreadRunning)
{
thread t(readTable);
}
but now t is block scope. So I want to declare t and then start the thread later so that t is accessible to other functions.
Thanks for any help.
std::thread's default constructor instantiates a std::thread without starting or representing any actual thread.
std::thread t;
The assignment operator moves the state of a thread object, and sets the assigned-from thread object to its default-initialized state:
t = std::thread(/* new thread code goes here */);
This first constructs a temporary thread object representing a new thread, transfers the new thread representation into the existing thread object that has a default state, and sets the temporary thread object's state to the default state that does not represent any running thread. Then the temporary thread object is destroyed, doing nothing.
Here's an example:
#include <iostream>
#include <thread>
void thread_func(const int i) {
std::cout << "hello from thread: " << i << std::endl;
}
int main() {
std::thread t;
std::cout << "t exists" << std::endl;
t = std::thread{ thread_func, 7 };
t.join();
std::cout << "done!" << std::endl;
}
As antred says in his answer, you can use a condition variable to make the thread to wait in the beginning of its routine.
Scott Meyers in his book “Effective Modern C++” (in the “Item 39: Consider void futures for one-shot event communication”) proposes to use void-future instead of lower level entities (boolean flag, conditional variable and mutex). So the problem can be solved like this:
auto thread_starter = std::promise<void>;
auto thread = std::thread([starter_future = thread_starter.get_future()]() mutable {
starter_future.wait(); //wait before starting actual work
…; //do actual work
});
…; //you can do something, thread is like “paused” here
thread_starter.set_value(); //“start” the thread (break its initial waiting)
Scott Meyers also warns about exceptions in the second … (marked by the you can do something, thread is like “paused” here comment). If thread_starter.set_value() is never called for some reasons (for example, due to exception throws in the second …), the thread will wait forever, and any attempt to join it would result in deadlock.
As both ways (condvar-based and future-based) contain hidden unsafety, and the first way (condvar-based) needs some boilerplate code, I propose to write a wrapper class around std::thread. Its interface should be similar to the one of std::thread (except that its instances should be assignable from other instances of the same class, not from std::thread), but contain additional void start() method.
Future-based thread-wrapper
class initially_suspended_thread {
std::promise<bool> starter;
std::thread impl;
public:
template<class F, class ...Args>
explicit initially_suspended_thread(F &&f, Args &&...args):
starter(),
impl([
starter_future = starter.get_future(),
routine = std::bind(std::forward<F>(f), std::forward<Args>(args)...)
]() mutable {if (starter_future.get()) routine();})
{}
void start() {starter.set_value(true);}
~initially_suspended_thread() {
try {starter.set_value(false);}
catch (const std::future_error &exc) {
if (exc.code() != std::future_errc::promise_already_satisfied) throw;
return; //already “started”, no need to do anything
}
impl.join(); //auto-join not-yet-“started” threads
}
…; //other methods, trivial
};
Condvar-based thread-wrapper
class initially_suspended_thread {
std::mutex state_mutex;
enum {INITIAL, STARTED, ABORTED} state;
std::condition_variable state_condvar;
std::thread impl;
public:
template<class F, class ...Args>
explicit initially_suspended_thread(F &&f, Args &&...args):
state_mutex(), state(INITIAL), state_condvar(),
impl([
&state_mutex = state_mutex, &state = state, &state_condvar = state_condvar,
routine = std::bind(std::forward<F>(f), std::forward<Args>(args)...)
]() {
{
std::unique_lock state_mutex_lock(state_mutex);
state_condvar.wait(
state_mutex_lock,
[&state]() {return state != INITIAL;}
);
}
if (state == STARTED) routine();
})
{}
void start() {
{
std::lock_guard state_mutex_lock(state_mutex);
state = STARTED;
}
state_condvar.notify_one();
}
~initially_suspended_thread() {
{
std::lock_guard state_mutex_lock(state_mutex);
if (state == STARTED) return; //already “started”, no need to do anything
state = ABORTED;
}
impl.join(); //auto-join not-yet-“started” threads
}
…; //other methods, trivial
};
There is no "standard" of creating a thread "suspended" which I assume is what you wanted to do with the C++ thread library. Because it is not supported on every platform that has threads, it is not there in the C++ API.
You might want to create a class with all the data it is required but not actually run your thread function. This is not the same as creating the thread but may be what you want. If so, create that, then later bind the object and its operator() or start() function or whatever to the thread.
You might want the thread id for your thread. That means you do actually need to start the thread function. However it can start by waiting on a condition variable. You then signal or broadcast to that condition variable later when you want it to continue running. Of course you can have the function check a condition after it resumes in case you might have decided to close it and not run it after all (in which case it will just return instantly).
You might want a std::thread object with no function. You can do that and attach it to a function later to run that function in a new thread.
I would give the thread a condition variable and a boolean called startRunning (initially set to false). Effectively you would start the thread immediately upon creation, but the first thing it would do is suspend itself (using the condition_variable) and then only begin processing its actual task when the condition_variable is signaled from outside (and the startRunning flag set to true).
EDIT: PSEUDO CODE:
// in your worker thread
{
lock_guard l( theMutex );
while ( ! startRunning )
{
cond_var.wait( l );
}
}
// now start processing task
// in your main thread (after creating the worker thread)
{
lock_guard l( theMutex );
startRunning = true;
cond_var.signal_one();
}
EDIT #2: In the above code, the variables theMutex, startRunning and cond_var must be accessible by both threads. Whether you achieve that by making them globals or by encapsulating them in a struct / class instance is up to you.
first declared in class m_grabber runs nothing. We assign member class object with new one with lambda function in launch_grabber method and thread with lambda runs within source class context.
class source {
...
std::thread m_grabber;
bool m_active;
...
}
bool source::launch_grabber() {
// start grabber
m_grabber = std::thread{
[&] () {
m_active = true;
while (true)
{
if(!m_active)
break;
// TODO: something in new thread
}
}
};
m_grabber.detach();
return true;
}
You could use singleton pattern. Or I would rather say antipattern.
Inside a singleton you would have std::thread object encapsulated. Upon first access to singleton your thread will be created and started.
I'm implementing simple server with boost::asio and thinking of io-service-per-cpu model(each io_service has one thread).
What i want to do is, let an io_service to request some jobs to another io_service( something like message passing ).
I think boost::asio::io_service::post can help me.
There are two io_services, ios1,ios2,
and a job(function) bool func(arg *),
and a completion handler void callback(bool).
So I want ios1 to request a job, ios2 runs it and notify ios1 to finish and finally ios2 runs the handler.
ios2.post(
[&ios1, arg_ptr, callback, func]
{
bool result = func(arg_ptr);
ios1.post( []{ callback(result) } );
} );
Is this code works? and is there any smarter and simpler way?
EDIT:
I found that the second lamda inside the ios1.post() can't reach the function pointer callback. It's out of the scope... so I'm trying another way using boost::bind().
ios2.post(
[&ios1, arg_ptr, callback, func]
{
ios1.post( boost::bind( callback, func(arg_ptr) ) );
} );
I removed one stack variable bool and it seems better.
But using c++11 lambda and boost::bind together doesn't look so cool.
How can i do this without boost::bind?
I found that the second lamda inside the ios1.post() can't reach the function pointer callback. It's out of the scope
I don't think that's the problem.
You're trying to capture callback but that's not a function pointer, it's a function. You don't need to capture a function, you can just call it! The same applies to func, don't capture it just call it. Finally, your inner lambda refers to result without capturing it.
It will work if you fix these problems:
ios2.post(
[&ios1, arg_ptr]
{
bool result = func(arg_ptr);
ios1.post( [result]{ callback(result); } );
}
);
You're second version is not quite the same, because func(arg_ptr) will get run in the thread of ios1 not ios2, and I'm not sure either version fits your description:
So I want ios1 to request a job, ios2 runs it and notify ios1 to finish and finally ios2 runs the handler.
In both your code samples ios1 runs the callback handler.
#include <boost/asio/io_service.hpp>
#include <boost/function.hpp>
typedef int arg;
int main()
{
arg * arg_ptr;
boost::function<void(bool)> callback;
boost::function<bool(arg *)> func;
boost::asio::io_service ios1, ios2;
ios2.post(
[&ios1, arg_ptr, callback, func]
{
bool result = func(arg_ptr);
auto callback1 = callback;
ios1.post( [=]{ callback1(result); } );
} );
}