[英]How to send signal from Singleton thread to another thread (Not singleton)
I'm facing a problem while creating a Singleton class with it's own thread that sends signal to another thread which is not a singleton class. 我在创建具有自己线程的Singleton类时遇到了一个问题,该类将信号发送到另一个不是Singleton类的线程。
Consumer.h 消费者
class Consumer : public QThread
{
Q_OBJECT
public:
explicit Consumer(QObject *parent = 0);
Consumer(Worker *Worker);
signals:
void toMessage(const bool& keepCycle);
public slots:
void getMessage(const QString& str);
private:
int m_counter;
};
Consumer.cpp Consumer.cpp
Consumer::Consumer(QObject *parent) :
QThread(parent)
{
m_counter = 0;
connect(Worker::Instance(), SIGNAL(sendMessage(QString)), this, SLOT(getMessage(QString)));
connect(this, SIGNAL(toMessage(bool)), Worker::Instance(), SLOT(fromMessage(bool)));
}
// Get's message from Singleton thread if counter > 5 sends signal to terminate cycle in Singleton thread
void Consumer::getMessage(const QString &str)
{
m_counter++;
if(m_counter <= 5) {
qDebug() << "Got message " << m_counter << ": " << str << "\n";
return;
}
else {
emit toMessage(false);
}
}
Singleton is done as follows (suspect it's Not Thread-safe ): 单例操作如下(怀疑它不是线程安全的 ):
template <class T>
class Singleton
{
public:
static T* Instance()
{
if(!m_Instance) m_Instance = new T;
assert(m_Instance != NULL);
return m_Instance;
}
protected:
Singleton();
~Singleton();
private:
Singleton(Singleton const&);
Singleton& operator=(Singleton const&);
static T* m_Instance;
};
template <class T> T* Singleton<T>::m_Instance = NULL;
And Worker Singleton class 和工人辛格尔顿班
class Worker : public QThread
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
void run();
signals:
void sendMessage(const QString& str);
public slots:
void fromMessage(const bool& keepCycle);
private:
volatile bool m_keepCycle;
};
typedef Singleton<Worker> Worker;
Worker.cpp 工作人员
Worker::Worker(QObject *parent) :
QThread(parent)
{
m_keepCycle = true;
}
void Worker::run()
{
while(true) {
if(m_keepCycle) {
QString str = "What's up?";
ElWorker::Instance()->sendMessage(str);
}
else {
qDebug() << "Keep Alive" << false;
break;
}
}
qDebug() << "Value of keepCycle" << m_keepCycle;
}
void Worker::fromMessage(const bool &keepCycle)
{
m_keepCycle = keepCycle;
qDebug() << "\nMessage FROM: " << keepCycle << "\n";
}
The main.cpp main.cpp
Consumer consumer;
ElWorker::Instance()->start();
consumer.start();
Can you help me to create thread-safe Singleton and to send signals between threads? 您可以帮助我创建线程安全的Singleton并在线程之间发送信号吗?
First of all, it is highly recommended to separate worker from it's thread: 首先,强烈建议将worker与它的线程分开:
class Object : public QObject
{
...
public slots:
void onStarted(); // if needed
void onFinished(); // if needed
...
};
...
mObject = QSharedPointer < Object >(new Object);
mThread = new QThread(this);
mObject->moveToThread(mThread);
connect(mThread, SIGNAL(started()), mObject, SLOT(onStarted())); // if needed
connect(mThread, SIGNAL(finished()), mObject, SLOT(onFinished())); // if needed
mThread->start();
Second of all, there are a lot of ways of creating a singleton. 其次,有很多创建单例的方法。 My favourite is this: 我最喜欢的是:
Object * obj(QObject *parent = 0)
{
static Object *mObj = new Object(parent);
return mObj;
}
...
obj(this); // creating
obj()->doStuff(); // using
Now, about thread-safety. 现在,关于线程安全。 Sending signals is thread-safe, unless you're sending pointers or non-constant references. 除非您要发送指针或非常量引用,否则发送信号是线程安全的。 Which, according to your code, you are not. 根据您的代码,您不是。 So, you should be fine. 所以,你应该没事。
UPDATE UPDATE
Actually, I didn't get how created thread-safe singleton above and I'm sending a signal from Worker TO Consumer Not a Thread itself? 实际上,我没有在上面得到如何创建线程安全的单例,并且我正在从Worker到Consumer而不是Thread本身发送信号? – hiken – 远足
obj
function mObj
is created and returned and each other time you call it, previously created mObj
is returned. 函数内部的静态值仅创建和初始化一次,因此,第一次调用obj
函数mObj
被创建并返回,而每次调用它时, mObj
返回先前创建的mObj
。 Also, I didn't say, it's thread-safe, all I said - I like this way better, then template one, because: 另外,我没有说过,它是线程安全的,我刚才说过-我更喜欢这种方式,然后选择一个模板,因为:
QObject
without problems 与QObject
没有问题 QThread
should be used for - is controlling thread's flow. QThread
唯一应用于-控制线程的流。 There are some situations, when you need to derive from QThread
and rewrite QThread::run
, but your case isn't one of them. 在某些情况下,当您需要从QThread
派生并重写QThread::run
,您的情况就不是其中一种。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.