I have gone through similar questions on Stackoverflow but still can't get a good answer:
how boost implements signals and slots
How signal and slots are implemented
I am quite puzzled on how this signal/slot is achieved.
Q1: From the following code, sig is connected to two function(Hello() and World()), and it seems that the functions are called in a serialized manner, which also implies that, one function(Hello()) need to be completed before going into another function(World())? => Single thread program
Q2: Are there anyway to enable multi-threaded signal/slot?(=> World() will start instantly, don't need to wait for Hello() to complete.) Or if it's not recommended, would you mind tell me why?
Sample codes on Boost website:
struct Hello
{
void operator()() const { std::cout << "Hello";}
};
struct World
{
void operator()() const { std::cout << ", World!" << std::endl;}
};
boost::signal<void ()> sig;
sig.connect(Hello());
sig.connect(World());
sig();
Output:
Hello, World!
Q1:
The calls are serialized. What signals are doing internally is, greatly simplified:
foreach connection:
call handler
Therefore you don't want to block in the handlers for long. If you need to do much work you can invoke it from there though, for example by creating a thread for it.
Q2:
boost signals 1 isn't even thread-safe; signals 2 is, but still does serialized calls. As signals are mostly used for event handling it is common style to not actually do much work in the handlers.
Thus there is no real benefit in calling them 'in parallel', the benefits would not in general justify the overhead of the neccessary thread invocations.
Q1: you are correct. Fixed my answer to the question you referenced to reflect that.
Q2: it seems you're confused by what should be threaded. In emitting/capturing process what contains code is the slot. So if you want to run the code concurrently, you should place the slots in different threads.
Such behavior is supported by Qt (don't know about boost, actually), and there's a chapter in qt manual that explains, that you most likely need "queued processing" for such behavior. But then you'll have to have the notion of "event loop" in the thread that executes the slot code (because you can't just tell the working thread "hey, stop doing your stuff, do this instead!").
If you don't want to wait, you'll have to spawn threads in slot codes directly. And you should not forget to use some kind of "wait" function in the code both slots have access to. By the way, both boost and Qt have nice wrappers around system threading libraries to do it easilly.
Related
I've faced quite an odd problem with QtConcurrent, mostly because of strange programming desires, maybe it's just an XY-problem, but...
So, there is my code, trying to communicate with the database, a backend code actually (on Qt, yes). It has to work quick and handle some requests, so I need a thread pool. As a well-known fact I suppose the connection establishing itself is a very time-consuming operation, so there is a need in persistent database connections resulting in persistent threads (QSqlDatabase cannot be moved around between the threads). Also it is quite natural to want asynchronous request handling, thus resulting in some need of a simple way to pass them to the persistent threads.
Nothing too complex, lets assume there already exists some boilerplate in a form like...
// That's what I want for now
QFuture<int> res = workers[i]->async(param1, param2);
// OR
// That's what I DO NOT want to get
workers[i]->async(param1, param2, [](QFuture<int> res) { // QFuture to pass exceptions
// callback here
});
That can be done for sure. Why not std::future? Well, it is much easier to use QFutureWatcher and it's signals for notifications about result's readiness. Pure C++ notification solutions are muuuch more complex and callbacks are also someting that has to be dragged through the class hierarchy. Each worker interfaces a thread with DB connections, obviously.
Okay, all of that can be written, but... custom thread pool would mean no QtConcurrent convenience, there seem to be only risky ways to create that QFuture so that it could be returned by the custom worker. QThreadPool is of no use, because it would be a whole big story to create persistent runnables in it. More to say, the boilerplate I've briefly described is gonna be some kind of project's core, used in many places, not something to be easily replaced by a 100 hand-made thread managings.
In short: if I could construst a QFuture for my results, the problem would be solved.
Could anyone point me to a solution or a workaround? Would be grateful for any bright ideas.
UPD:
#VladimirBershov offered a good modern solution which implements observer pattern. After some googling I've found a QPromise library. Of course, constructing a custom QFuture is still hacky and can be only done via undocumented QFutureInterface class, but still some "promise-like" solution makes asynchronous calls neater by far as I can judge.
You can use AsyncFuture library as a custom QFuture creation tool or ideas source:
AsyncFuture - Use QFuture like a Promise object
QFuture is used together with QtConcurrent to represent the result of
an asynchronous computation. It is a powerful component for
multi-thread programming. But its usage is limited to the result of
threads, it doesn't work with the asynchronous signal emitted by
QObject. And it is a bit trouble to setup the listener function via
QFutureWatcher.
AsyncFuture is designed to enhance the function to offer a better way
to use it for asynchronous programming. It provides a Promise object
like interface. This project is inspired by AsynQt and RxCpp.
Features:
Convert a signal from QObject into a QFuture object
Combine multiple futures with different type into a single future object
Use Future like a Promise object
Chainable Callback - Advanced multi-threading programming model
Convert a signal from QObject into a QFuture object:
#include "asyncfuture.h"
using namespace AsyncFuture;
// Convert a signal from QObject into a QFuture object
QFuture<void> future = observe(timer, &QTimer::timeout).future();
/* Listen from the future without using QFutureWatcher<T>*/
observe(future).subscribe([]() {
// onCompleted. It is invoked when the observed future is finished successfully
qDebug() << "onCompleted";
},[]() {
// onCanceled
qDebug() << "onCancel";
});
My idea is to use thread pools with maximum 1 thread available for each.
QThreadPool* persistentThread = new QThreadPool; // no need to write custom thread pool
persistentThread->setMaxThreadCount(1);
persistentThread->setExpiryTimeout(-1);
and then
QFuture<int> future_1 = QtConcurrent::run(persistentThread, func_1);
QFuture<int> future_2 = QtConcurrent::run(persistentThread, func_2);
func_2 will be executed after func_1 in the same one "persistent" thread.
I have some existing code that uses std::future/std::promise that I'd like to integrate with a Qt GUI cleanly.
Ideally, one could just:
std::future<int> future{do_something()};
connect(future, this, &MyObject::resultOfFuture);
and then implement resultOfFuture as a slot that gets one argument: the int value that came out of the std::future<int>. I've added this suggestion as a comment on QTBUG-50676. I like this best because most of my future/promises are not concurrent anyway, so I'd like to avoid firing up a thread just to wait on them. Also, type inference could then work between the future and the slot's parameter.
But it seems to me that this shouldn't be hard to implement using a wrapper Qt object (e.g., a version of QFutureWatcher that takes a std::future<int>). The two issues with a wrapper are:
the wrapper will have to be concrete in its result type.
the watcher would have to be concurrent in a thread?
Is there a best-practice to implement this sort of connection? Is there another way that can hook into the Qt main loop and avoid thread creation?
std::future is missing continuations. The only way to turn the result of a std::future asynchronously into a function call delivering the result is to launch a thread watching it, and if you want to avoid busy-waiting you need one such thread per std::future, as there is no way to lazy-wait on multiple futures at once.
There are plans to create a future with continuation (a then operation), but they are not in C++ as of c++17 let alone c++11.
You could write your own system of future/promise that mimics the interface of std::future and std::promise that does support continuations, or find a library that already did that.
A busy-wait solution that regularly checked if the future was ready could avoid launching a new thread.
In any case, std::experimental::then would make your problem trivial.
future.then( [some_state](auto future){
try {
auto x = future.get();
// send message with x
} catch( ... ) {
// deal with exception
}
} );
you can write your own std::experimetnal::future or find an implementation to use yourself, but this functionality cannot be provided without using an extra thread with a std::future.
For purposes of thread local cleanup I need to create an assertion that checks if the current thread was created via boost::thread. How can I can check if this was the case? That is, how can I check if the current thread is handled by boost::thread?
I simply need this to do a cleanup of thread local storage when the thread exits. Boost's thread_local_ptr appears to only work if the thread itself is a boost thread.
Note that I'm not doing the check at cleanup time, but sometime during the life of the thread. Some function calls one of our API/callbacks (indirectly) causing me to allocate thread-local storage. Only boost threads are allowed to do this, so I need to detect at that moment if the thread is not a boost thread.
Refer to Destruction of static class members in Thread local storage for the problem of not having a generic cleanup handler. I answered that and realized pthread_clenaup_push won't actually work: it isn't called on a clean exit form the thread.
While I don't have answer to detect a boost thread the chosen answer does solve the root of my problem. Boost thread_specific_ptr's will call their cleanup in any pthread. It must have been something else causing it not to work for me, as an isolated test shows that it does work.
The premise for your question is mistaken :) boost::thread_specific_ptr works even if the thread is not a boost thread. Think about it -- how would thread specific storage for the main thread work, seeing as it's impossible for it to be created by boost? I have used boost::thread_specific_ptr from the main thread fine, and although I haven't examined boost::thread_specific_ptr's implementation, the most obvious way of implementing it would work even for non-boost threads. Most operating systems let you get a unique ID number for the current thread, which you can then use as an index into a map/array/hashtable.
More likely you have a different bug that prevents the behavior you're expecting to see from happening. You should open a separate question with a small compilable code sample illustrating the unexpected behavior.
You can't do this with a static assertion: That would mean you could detect it at compile time, and that's impossible.
Assuming you mean a runtime check though:
If you don't mix boost::thread with other methods, then the problem just goes away. Any libraries that are creating threads should already be dealing with their own threads automatically (or per a shutdown function the API documents that you must call).
Otherwise you can keep, for example, a container of all pthread_ts you create not using boost::thread and check if the thread is in the container when shutting down. If it's not in the container then it was created using boost::thread.
EDIT: Instead of trying to detect if it was created with boost::thread, have you considered setting up your application so that the API callback can only occur in threads created with boost::thread? This way you prevent the problem up front and eliminate the need for a check that, if it even exists, would be painful to implement.
Each time a boost thread ends, all the Thread Specific Data gets cleaned. TSD is a pointer, calling delete p* at destruction/reset.
Optionally, instead of delete p*, a cleanup handler can get called for each item. That handler is specified on the TLS constructor, and you can use the cleanup function to do the one time cleaning.
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>
void cleanup(int* _ignored) {
std::cout << "TLS cleanup" << std::endl;
}
void thread_func() {
boost::thread_specific_ptr<int> x(cleanup);
x.reset((int*)1); // Force cleanup to be called on this thread
std::cout << "Thread begin" << std::endl;
}
int main(int argc, char** argv) {
boost::thread::thread t(thread_func);
t.join();
return 0;
}
It seem that the only implementation that provide Safe Cross-Thread Signals for both the Signal class and what's being called in the slot is QT. (Maybe I'm wrong?).
But I cannot use QT in the project I'm doing. So how could I provide safe Slots call from a different thread (Using Boost::signals2 for example)? Are mutex inside the slot the only way? I think signals2 protect themself but not what's being done inside the slot.
Thanks
You can combine boost::bind and boost ASIO to create Cross-Thread Calls.
# In Thread 2
boost::asio::io_service service;
boost::asio::io_service::work work (service); // so io service won't stop if there is no work
service.run() # starting work thread
# In Thread 1
service.post (boost::bind (&YourClass::function, &yourClassInstance, parameter1, parameter2))
Thread 2 will go into a loop and will execute your bound function. I think you can also call Boost::Signals2 calls into this loop.
But keep care: If you do cross-thread-signaling, make sure that the destination object still exists when being called. You can garantuee that by dropping all connections in your targets destructor (not in their base class destructor, also see Signals-Trackable Class)
I do not like Boost::Signals2 oo much, because of its very long stack trace and compile times (blog post).
It's not a signals-slots implementation, exactly, but there's a C++ implementation of Twisted's Deferred pattern that accomplishes a similar goal to a cross-thread signal-slot mechanism. If someone doesn't come along and post a better solution, it might be worth a look: http://sourceforge.net/projects/deferred/
Follow up question to:
This question
As described in the linked question, we have an API that uses an event look that polls select() to handle user defined callbacks.
I have a class using this like such:
class example{
public:
example(){
Timer* theTimer1 = Timer::Event::create(timeInterval,&example::FunctionName);
Timer* theTimer2 = Timer::Event::create(timeInterval,&example::FunctionName);
start();
cout<<pthread_self()<<endl;
}
private:
void start(){
while(true){
if(condition)
FunctionName();
sleep(1);
}
}
void FunctionName(){
cout<<pthread_self()<<endl;
//Do stuff
}
};
The idea behind this is that you want FunctionName to be called both if the condition is true or when the timer is up. Not a complex concept. What I am wondering, is if FunctionName will be called both in the start() function and by the callback at the same time? This could cause some memory corruption for me, as they access a non-thread safe piece of shared memory.
My testing tells me that they do run in different threads (corruption only when I use the events), even though: cout<<pthread_self()<<endl; says they have the same thread id.
Can someone explains to me how these callbacks get forked off? What order do they get exectued? What thread do they run in? I assume they are running in the thread that does the select(), but then when do they get the same thread id?
The real answer would depend on the implementation of Timer, but if you're getting callbacks run from the same thread, it's most likely using signals or posix timers. Either way, select() isn't involved at all.
With signals and posix timers, there is very little you can do safely from the signal handler. Only certain specific signal safe calls, such as read() and write() (NOT fread() and fwrite(), or even new and cout) are allowed to be used. Typically what one will do is write() to a pipe or eventfd, then in another thread, or your main event loop running select(), notice this notification and handle it. This allows you to handle the signal in a safe manner.
Your code as written won't compile, much less run. Example::FunctionName needs to be static, and needs to take an object reference to be used as a callback function.
If the timers run in separate threads, it's possible for this function to be called by three different threads.