我在使用自己的线程创建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::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完成如下(怀疑它是非线程安全):
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;
工人单身人士课程
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";
}
main.cpp
Consumer consumer;
ElWorker::Instance()->start();
consumer.start();
你能帮我创建线程安全的Singleton并在线程之间发送信号吗?
答案 0 :(得分:0)
首先,强烈建议将工作人员与其分开:
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();
其次,有很多方法可以创建单身人士。我最喜欢的是:
Object * obj(QObject *parent = 0)
{
static Object *mObj = new Object(parent);
return mObj;
}
...
obj(this); // creating
obj()->doStuff(); // using
现在,关于线程安全。发送信号是线程安全的,除非您发送指针或非常量引用。根据你的代码,你不是。所以,你应该没事。
<强>更新强>
实际上,我没有得到上面创建的线程安全单例的方法,而且我还没有 从工人发送信号到消费者不是线程本身? - hiken
obj
函数mObj
时会创建并返回,并且每隔一次调用它,之前创建的{{1}返回。另外,我没有说,它是线程安全的,我所说的 - 我更喜欢这种方式,然后是模板一,因为:
mObj
合作无问题QObject
的东西 - 是控制线程的流程。在某些情况下,您需要从QThread
派生并重写QThread
,但您的情况不是其中之一。