I'm using sigslot library to trigger signals in a function. This function runs in a thread using QtConcurrent::run, and signals are connected in the main thread.
It's quite working as expected, except that the signal connection doesn't work every time (let's say around 25% failure).
This erratic behavior is problematic and I can't find a solution. Signals in sigslot library have different options depending on the multithreading context, but none of them is fixing the problem.
Before trying boost, I really would like to find a solution to keep using sigslot since it's a quite simple library and I only need a basic use of signals and slots in this part of the code. And I don't want to use Qt for this because I prefer to leave this same part of the code free of Qt.
Any hint would be much appreciated.
Update : for some reason, using as a desperate try sigslot::single_threaded appears to give way better results.
signal1<int, single_threaded> Sig1;
I'm not saying it's solving the problem since it doesn't make sense to me. As explained in the documentation :
Single Threaded In single-threaded mode, the library does not attempt to protect its internal data structures
across threads. It is therefore essential that all calls to constructors, destructors and signals
must exist within a single thread.
Update 2 :
Here is a MWE. But results are quite random. Sometimes it fully works, sometimes not all. I know it sounds weird, but that's the problem. I also tried boost::signals2 instead of sigslot, but result is quite the same. There's a executable bad access in boost::signals2::mutex::lock()
class A {
public :
A() {}
~A() {}
sigslot::signal1<int, sigslot::multi_threaded_local> sigslot_signal;
boost::signals2::signal<void (int)> boost_signal;
void func_sigslot() {
for (int i=0;i<4;i++) {
sigslot_signal.emit_signal(i);
}
}
void func_boost() {
for (int i=0;i<4;i++) {
boost_signal(i);
}
}
};
class B : public sigslot::has_slots<sigslot::multi_threaded_local> {
public :
B() {}
~B() {}
void test(int i) {
std::cout << "signal triggered, i=" << i << std::endl;
}
};
void main() {
A a;
B b;
a.sigslot_signal.connect_slot(&b, &B::test);
a.boost_signal.connect(boost::bind(&B::test, &b, _1));
QtConcurrent::run(&a, &A::func_sigslot);//->crashes when signal emitted
QtConcurrent::run(&a, &A::func_boost);//->crashes when signal emitted
boost::thread t1(boost::bind(&A::func, &a));
t1.join();//works fine
}
The Sarah Thompson's sigslot library (if that's what you use) is old, unsupported, and seems quite buggy. There's no test harness of any sort. The original source doesn't compile under modern compilers. There are typos there that were hidden due to MSVC's former treatment of templates as token lists: obviously parts of the code were never used!
I highly suggest that you simply use Qt, or a different signal-slot library.
Alas, your approach can't work: the sigslot library has no idea about Qt's thread contexts, and doesn't integrate with Qt's event loop. The slots are called from the wrong thread context. Since you likely didn't write your slots to be thread-safe, they don't do the right thing and appear not to work.
The sigslot library's threading support only protects the library's own data, not your data. Setting the multithreading policies only affects the library's data. This is in stark contrast with Qt, where each QObject's thread context is known and enables the signal-slot system to act safely.
In order to get it to work, you need to expose a thread-safe interface in all the QObject's whose slots you're invoking. This can be as simple as:
class Class : public QObject {
Q_OBJECT
public:
Class() {
// This could be automated via QMetaObject and connect overload
// taking QMetaMethod
connect(this, &Class::t_slot, this, &Class::slot);
}
Q_SIGNAL void t_slot();
Q_SLOT slot() { ... }
}
Instead of connecting to slot(), connect to t_slot(), where the t_ prefix stands for threadsafe/thunk.
Related
The normal way is with invokeMethod:
QMetaObject::invokeMethod(this, "methodName", Qt::QueuedConnection);
which works fine, except that I don't want to write methods in strings. Like ever. Why? Because this is a refactoring nightmare. Imagine having to change a method name for some reason. The software will malfunction and I'll have to notice in stderr that the method doesn't exist.
My solution?
I use QTimer. Like this:
QTimer::singleShot(0, this, &ClassName::methodName);
which seems to work fine. What I like about this is that you can replace the &ClassName::methodName part with a lambda/bind and it'll still be bound to the correct object (in case I need to use it with QThread) with the expected variable referencing we understand in standard C++:
QTimer::singleShot(0, threadObject, [this, param1, ¶m2](){ this->methodName(param1, param2); });
Better solutions exist?
But... I'm hoping there's a better way to do this because someone reading my code will not understand why I'm using a QTimer here... so I gotta comment everything.
Is there a better way to do this that's compatible with versions of Qt down to 5.9 or 5.7? What's the best solution you know?
Since Qt 5.10 there are functor-based overloads of QMetaObject::invokeMethod.
This means that you can ditch the string-based approach and use the modern way of calling methods with invokeMethod too.
Actually QTimer is not an asynchronous way to solve your problem. It pushes your method onto the stack to call your method when the currently executing method exits.
I think that the better solution is to use QtConcurrent run. It will execute your method in async way.
It is simple to use it:
QtConcurrent::run(&myFunc); // some function
QtConcurrent::run(this, &MyClass::method); // for class method
QtConcurrent::run(this, &MyClass::methodWithParams, param1, param2); // for class method with params
Also, you should include concurrent to your .qmake file like this:
...
QT += concurrent
...
If you need a result of function, you can use QFuture class.
It's not much different from what you're already doing, but I've done it by connecting to the destruction of a QObject instead of using a QTimer.
template <typename Func>
void MyClass::runLater(Func &&func)
{
QObject toBeDestroyed;
QObject::connect(&toBeDestroyed, &QObject::destroyed, this, func, Qt::QueuedConnection);
}
And then I can call it with a lambda:
void doSomething(const QString &text, int num)
{
runLater([text, num]() { qDebug() << text << num; });
}
Currently I'm aware of the following Dispatcher objects.
If you have a text view, you can use IWpfTextView.VisualElement.Dispatcher.
If your class is constructed by MEF (marked with [Export] and not directly constructed from your own code), then you can use the fact that the MEF part resolution algorithm and construction occurs on the UI thread, allowing the use of Dispatcher.CurrentDispatcher. For example:
[Export(typeof(ISomeInterface))]
public class MyClass : ISomeInterface {
private readonly Dispatcher _dispatcher;
public MyClass() {
_dispatcher = Dispatcher.CurrentDispatcher.
}
}
You can use Application.Current.Dispatcher from any code.
What, if any, is the recommended practice for obtaining a Dispatcher?
Do not take a dependency on MEF composing on UI thread. If it works for you right now, you're just getting lucky. Also MEF is delayed in nature and full of Lazy, so if you happen to realize it on a background thread, the entire subgraph will get realized on background.
I would use #1 or #3 (doesn't matter which, there is only one UI thread dispatcher, doesn't matter how you get to it).
Consider signal manager that receives the signal, checks for some conditions, and if they are met, transmits signal to slot, discarding signal otherwise:
signal(some args) ---> [manager] ---> slot(some args)
I can implement it for each given set of arguments using QMetaObject::invokeMethod, say for void signal(int) and void slot(int):
.h
class Manager: public QObject
{
Q_OBJECT
public:
Manager(QObject* sender,const char* signal, QObject* recv, const char* slot);
private:
bool isOkToSend();
QString slotInvokeSyntax;
QObject *recv;
private slots:
On_Signal(int);
}
.cpp
Manager::Manager(QObject* sender,const char* signal, QObject* recvIn, const char* slot)
: slotInvokeSyntax(slot)
, recv(recvIn)
{
connect(sender,signal,this,SLOT(On_Signal(int));
//retrieving method name only
slotInvokeSyntax.remove(0,1).remove(QRegExp("(*",Qt::CaseSensitive,QRegExp::Wildcard));
}
Manager::On_Signal(int val)
{
//invoking slot
if(isOkToSend())
QMetaObject::invokeMethod(recv,slotInvokeSyntax.toAscii().constData(),Q_ARG(int,val));
}
I would like to somehow generalize this for signals and slots with generic number/type of arguments - so that manager works on any pairs like signal(QString)-slot(QString), signal(int,int)-slot(int,int), ...
Is there any way to implement this functionality without adding slot for each of the argument types in Manager? In case my approach is in wrong in general, any suggestions on how to implement such manager are welcome!
EDIT
A bit of clarification on what am I trying to implement - I have large system with several possible states consisting of many smaller widgets (or sub-systems) (some sub-systems can also act both as stand-alone applications or as a part of the larger system). I'm trying to implement global observer that intercepts certain ui events (such as buttons clicks, edits in QLineEdit, QDropbox changes, etc.), and either let corresponding slot of the widget to be called, or discards it if desired action interferes with the global state of the system. I would like to do it through intercepting signal since it allows to avoid dependencies between system components and compiling each subsystem as stand-alone library (with observer not being dependent on any other part of the system and thus being put in core library), but I'm open to any other alternatives that will allow me to achieve that!
FYI, whenever you use something like this:
QString foo;
something(foo.toAscii().constData());
...you are accessing already freed memory because the data pointed to by the QByteArray::constData are valid only until the QByteArray instance lives and is not modified. In your case, the QByteArray is a temporary created by calling foo.toAscii() and is destroyed before the something is called. So this will crash at some point. edit: this does not apply to function calls, see the comments.
To your question -- it would be interesting to know what you're trying to achieve here. The Qt's metatype and metaobject system is indeed a rich one, but abusing it too much might not be the most ellegant way of solving your problem. That said, it's probably fine to use it in this "creative" way with mocked objects, in unit tests etc.
I haven't done this myself and I am not sure whether it's doable without having to touch the q_static_metacall, but it looks like QObject generic signal handler contains an answer to your question.
After Edit:
You said you're looking for a something like a common event bus; the alleged reason is to avoid excess rebuilds when the individual components change. I would not introduce a central interceptor to this architecture. If the toal amount of states is reasonably small, why don't you just let something emit signals upon entering a particular state and have all of your components react to that by enabling/disabling the individual QActions?
I am using a small embedded RTOS which supports threads. I am programming in C++ and want to create a class that will allow me to run an arbitrary member function of any class as a thread. The RTOS does not directly support creating threads from member functions but they work fine if called from withing a thread. Boost::thread is not available on my platform.
I am currently starting threads in an ad-hoc fashion through a friend thread_starter() function but it seems that I must have a seperate one of these for each class I want to run threads from. My current solution of a thread base class uses a virtual run() function but this has the disadvantage that I can only start 1 thread for a class and that is restricted to the run() function + whatever that calls in turn (ie I cannot run an arbitrary function from within run() elegantly)
I would ideally like a class "thread" that was templated so I could perform the following from within a class "X" member function :
class X
{
run_as_thread(void* p)';
};
X x;
void* p = NULL;
template<X>
thread t(x, X::run_as_thread, p);
//somehow causing the following to be run as a thread :
x->run_as_thread(p);
Sorry if this has been done to death here before but I can only seem to find references to using Boost::thread to accomplish this and that is not available to me. I also do not have access to a heap so all globals have to be static.
Many thanks,
Mike
If your compiler is modern enough to support the C++11 threading functionality then you can use that.
Maybe something like this:
class X
{
public:
void run(void *p);
};
X myX;
void *p = nullptr;
std::thread myThread(std::bind(&X::run, myX, p));
Now X::run will be run as a thread. Call std::thread::join when the thread is done to clean up after it.
Assuming your RTOS works a bit like pthreads, and you don't have C++11 (which probably makes assumptions about your threading support) you can use this sort of mechanism, but you need a static method in the class which takes a pointer to an instance of the class. Thus (roughly)
class Wibble
{
public:
static void *run_pthread(void *me)
{
Wibble *x(static_cast<Wibble *>(me));
return x->run_thread_code();
}
private:
void *run_thread();
};
Wibble w;
pthread_create(&thread, &attr, Wibble::run_pthread, &w);
Passing arguments is left as an exercise to the reader...
This can be templatised with a bit of effort, but it's how the guts is going to need to work.
Have a look at my post on passing C++ callbacks between unrelated classes in non-boost project here.
It sounds like what you are asking is a way to run an arbitrary member function on a class asynchronously. I take it from your comment about the virtual run() function:
"this has the disadvantage that I can only start 1 thread for a class"
...to mean that you do not like that option because it causes all function calls to execute in that thread, when what you want is the ability to have individual function calls threaded off, NOT just create an object-oriented thread abstraction.
You should look into a thread pooling library for your target platform. I can't offer any concrete suggestions given no knowledge of your actual platform or requirements, but that should give you a term to search on and hopefully get some fruitful results.
I'm trying to port a C# thread pool into C++ but have encountered some serious problems. Some of the features of the C# thread pool are:
Define the maximum number of concurrent threads explicitly
Each thread is defined using a AutoResetEvent
Each workitem in the thread are overloaded so that it can have delegate functions as its private members.
For example,
private static void RunOrBlock(WorkItem workitem) {
workItem.ThreadIndex = WaitHandle.WaitAny(threadUnoccupied);
ThreadPool.QueueUserWorkItem(threadWorker, workItem);
}
private static void threadWorker(object o) {
WorkItem workItem = (workItem) o;
workItem.Run();
threadUnoccupied[workItem.ThreadIndex].Set();
}
WorkItem is defined as:
public abstract class WorkItem {
protected int threadIndex;
public abstract void Run();
public int ThreadIndex {
get { return threadIndex; }
set { threadIndex = value; }
}
Does someone know if there exists a open-source threading pool that has similar functionalities? If not, what will be the correct way to implement such a threading pool? Thanks!
I'm not certain about their specific functionalities, but for open source threadpools in c++ look at boost threadpool or zthreads.
If you just need a threadpool like functionality and have a compiler which supports it, you could also just use openmp 3.0 tasks. This is what I would choose if possible, since "boost" threadpool didn't look very convincing at a glance (so might have quite a bit of overhead) and it seems like zthreads isn't actively developed anymore (at least at first glance, I'm not 100% sure).
In the not exactly foss, but might be usable if you can live with the licensing (or are ready to invest quite a bit of money...) Intel Threading Building Blocks is pretty much treadpool based