ОК для тех, кто тоже пытается решить эту проблему, думаю, я понял это, если я переместлю объекты m_timer и multitimer обратно в основной поток qt и сгенерирую сигнал запуска таймера «правильно», все это, кажется, работает (см. Ниже)).
Возможно, я все еще мог бы сделать exec-вызов в qthread, чтобы перенять его из pthread и переместить мультитимер и m_timer к нему, но пока этот способ работает, и я получаю свой "Получено по таймеру%d. \ n "вывод вовремя даже после того, как pthread мертв, как хотелось бы.:
Спасибо всем за ввод, если есть лучший способ сделать это или огромная ошибка, которую я упустил, было бы хорошознать?Cheers
multitimer.h:
/**
@file multitimer.h
@brief Partial implementation of Windows-like SetTimer()/KillTimer() for Qt.
*/
#pragma once
#ifndef MULTI_TIMER_H
#define MULTI_TIMER_H
#include <QThread>
#include <QTimer>
#include <QMutex>
#include <QMap>
#include <QMetaType>
#include <cassert>
class MultiTimer : public QThread
{
Q_OBJECT
public:
typedef void (*multiTimerCallback)(quint32 p_id);
private:
QTimer m_timer;
QMutex m_mutex;
quint32 m_id;
multiTimerCallback m_callback;
void KillTimer(void);
public:
// only TimerFactory is allowed to instantiate MultiTimer
MultiTimer(quint32 p_id, multiTimerCallback p_callback);
~MultiTimer();
enum TTimerType
{
TT_SingleShot, ///< Timer fires only once
TT_Repetitive ///< Timer keeps firing repeatedly until stopped with KillTimer()
};
void SetTimer(quint32 p_delayInMilliseconds, MultiTimer::TTimerType timerType);
private slots:
void Update(void);
signals:
void start_sig(int);
};
#endif
timer.cpp:
#include <QtCore/QCoreApplication>
#include "multitimer.h"
#include <stdio.h>
//--------------------------------------------------------------------------------------------------
void MultiTimer::SetTimer(quint32 p_delayInMilliseconds, MultiTimer::TTimerType timerType)
{
QMutexLocker locker(&m_mutex);
m_timer.setSingleShot(TT_SingleShot == timerType ? true : false);
connect(this, SIGNAL(start_sig(int)), &m_timer, SLOT(start(int)), Qt::QueuedConnection);
//m_timer.start(p_delayInMilliseconds);
emit start_sig(p_delayInMilliseconds);
disconnect(this, SIGNAL(start_sig(int)), &m_timer, SLOT(start(int)));
}
void MultiTimer::KillTimer(void)
{
QMutexLocker locker(&m_mutex);
m_timer.stop();
}
void MultiTimer::Update(void)
{
QMutexLocker locker(&m_mutex);
if (NULL != m_callback)
m_callback(m_id);
}
MultiTimer::MultiTimer(quint32 p_id, multiTimerCallback p_callback)
: m_id(p_id)
, m_callback(p_callback)
{
bool isConnected = true;
isConnected &= this->connect(&this->m_timer, SIGNAL(timeout()), this, SLOT(Update()), Qt::QueuedConnection);
assert(isConnected);
//this->start();
moveToThread(qApp->thread());
m_timer.moveToThread(qApp->thread());
}
MultiTimer::~MultiTimer()
{
KillTimer();
wait();
}
//--------------------------------------------------------------------------------------------------
#define ASYNC_TIMERS
#define xGLOBAL_TIMERS
void Callback(quint32 p_id)
{
printf("Got timered by timer %d.\n", p_id);
}
MultiTimer *mt;
void StartTimers(void)
{
#ifndef GLOBAL_TIMERS
mt = new MultiTimer(1, Callback);
#endif
mt->SetTimer(2000, MultiTimer::TT_SingleShot);
}
#ifdef ASYNC_TIMERS
pthread_t AsyncTaskThread;
void *ProcessAsyncTasks(void */*ptr*/)
{
StartTimers();
return NULL;
}
#endif
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
#ifdef GLOBAL_TIMERS
mt = new MultiTimer(1, Callback);
#endif
#ifdef ASYNC_TIMERS
pthread_create(&AsyncTaskThread, NULL, &ProcessAsyncTasks, NULL);
#else
StartTimers();
#endif
return a.exec();
}