Qt Android,如何访问QRunnable中的外部对象?

时间:2015-03-14 12:06:39

标签: android multithreading qt qthread qtandroidextras

我有一个在桌面上运行良好但在android上崩溃的线程类。在我的Qt应用程序中,我需要一个包含这样的共享对象的任务:

class UpdateTask : public QRunnable
{
    MyPointer * _p;
    void run()
    {
        qDebug() << "Hello world from thread" << QThread::currentThread();
        _p.write();
        qDebug() << "Hello3 world from thread" << QThread::currentThread();
    }
public:
    UpdateTask ();
    ~UpdateTask ();
    void setPointer(MyPointer * pointer){
        _p = pointer;
    }
};

在main中,我希望能够按如下方式运行Task:

UpdateTask * task = new UpdateTask ();
task->setPointer(_pointer);
QThreadPool::globalInstance()->start(task);

这完全适用于桌面。但在android中你可能知道它不起作用。当我运行Fatal signal 11 (SIGSEGV), code 1, fault addr 0x98 in tid 31727 (Thread (pooled))时,只有第一个Hello打印才会使用_p
所以我的问题是:
如何在所有线程中使用MyPointer(共享对象)。我不可能将它的副本传递给每个线程。它应该通过所有线程中的指针传递。换句话说,我怎么能在所有线程中使用共享对象。在非const的方法中,每个线程都可以更改对象 我知道有几种技术可以处理Qt中的多线程应用程序。哪一个适合在Android设备上工作?
我是否需要在Android中使用JNI进行安全的多线程处理?我想我做了!

1 个答案:

答案 0 :(得分:2)

通过使用互斥锁或信号量或其他东西包装对指针的访问来使其成为线程安全。

另一种方法是使用排队信号插槽连接发送它。

以下是使用互斥锁执行此操作的一种方法:

// Member variable of UpdateTask
QMutex m_mutex;
// In your constructor
_p = 0;

void UpdateTask::setPointer(MyPointer *pointer)
{
    QMutexLocker locker(&m_mutex);
    _p = pointer;
}

void UpdateTask::run()
{
    // Create connections here, and the thread affinity will be correct, 
    // otherwise you need to use moveToThread() or explicitly say a 
    // Qt::QueuedConnection


    // Any place where _p is accessed
    {
        QMutexLocker locker(&m_mutex);
        if(p != 0)
            p->write();
    }
}

http://doc.qt.io/qt-5/qmutexlocker.html#details

希望有所帮助。