Qt 线程QThread

线程

线程中无法使用任何界面部件类,所以界面与线程之间的协作通过信号和槽或者其他通信机制。

1、线程类

QThread类

2、相关信号

[signal] void QThread::finished()     //线程终止结束时发出的信号
[signal] void QThread::started()     //线程开始运行发出的信号

3、相关槽

[slot] void QThread::quit()   //线程退出
[slot] void QThread::start(Priority priority = InheritPriority) //线程启动函数
[slot] void QThread::terminate() 
//终止线程的运行,可能立马终止,也可能延迟终止,时间不确定,取决于操作系统的调度机制。
//可以使用QThread::wait()来确保线程退出,一般情况最好不要用这个函数

4、常用方法

4.1 线程阻塞
bool QThread::wait(unsigned long time = ULONG_MAX)   //阻塞线程,类似POSIX中的pthread_join()
4.2 线程退出
void QThread::exit(int returnCode = 0)    //线程退出
4.3 线程睡眠延时
[static] void QThread::msleep(unsigned long msecs) 
[static] void QThread::sleep(unsigned long secs)
[static] void QThread::usleep(unsigned long usecs)
4.4 进入事件循环
[protected] int QThread::exec()

5、线程的状态

bool QThread::isFinished() const //判断线程是否终止
bool QThread::isRunning() const  //线程是否是运行状态

6、获取线程ID

6.1 获取线程相对应的对象
[static] QThread *QThread::currentThread()
6.2 获取当前线程的句柄
[static] Qt::HANDLE QThread::currentThreadId()

7、设置/获取线程参数

常用设置参数方法,一般用默认即可。

7.1 设置/获取线程优先级
void QThread::setPriority(Priority priority)
    
Priority QThread::priority() const
7.2 设置/获取线程栈大小
void QThread::setStackSize(uint stackSize)

uint stackSize() const

8、线程入口函数

[virtual protected] void QThread::run()
//虚保护函数,由用户重写

9、线程同步

9.1 互斥锁
QMutex类

9.2 读写锁

QReadWriteLock 类

允许多进程读,不可以多进程写

9.3 信号量

QSemaphore类

9.4 条件变量

QWaitContion类

参考Qt提供的示例 Wait Conditions Example

QThread简单使用

#include <QMainWindow>
#include <QProcess>
#include <QThread>

namespace Ui {
    
    
class MainWindow;
}

class TestThread;

class MainWindow : public QMainWindow
{
    
    
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    TestThread *myTestThread;
};

class TestThread : public QThread
{
    
    
protected:
    virtual void run();
public:
    TestThread();
    void startThread();
    void stopThread();
private:
    bool threadStatus;
};


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);

    myTestThread = new TestThread;

    connect(ui->pushButton_2, &QPushButton::clicked, this->myTestThread, &TestThread::startThread);
    connect(ui->pushButton_3, &QPushButton::clicked, this->myTestThread, &TestThread::stopThread);
}

void TestThread::run()
{
    
    
    static int cnt = 0;
    while (threadStatus)
    {
    
    
        qDebug() << "thread is running" << cnt++;
        this->sleep(1);
    }
}

TestThread::TestThread()
{
    
    
    this->threadStatus = 0;     //线程还没运行
}

void TestThread::startThread()
{
    
    
    this->threadStatus = 1;
    this->start();
}

void TestThread::stopThread()
{
    
    
    this->threadStatus = 0;
    this->quit();
}

参考手册还提供了一种特别创建线程的方法:

class Worker : public QObject
  {
    
    
      Q_OBJECT

  public slots:
      void doWork(const QString &parameter) {
    
    
          QString result;
          /* ... here is the expensive or blocking operation ... */
          emit resultReady(result);
      }

  signals:
      void resultReady(const QString &result);
  };

  class Controller : public QObject
  {
    
    
      Q_OBJECT
      QThread workerThread;
  public:
      Controller() {
    
    
          Worker *worker = new Worker;
          worker->moveToThread(&workerThread);
          connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
          connect(this, &Controller::operate, worker, &Worker::doWork);
          connect(worker, &Worker::resultReady, this, &Controller::handleResults);
          workerThread.start();
      }
      ~Controller() {
    
    
          workerThread.quit();
          workerThread.wait();
      }
  public slots:
      void handleResults(const QString &);
  signals:
      void operate(const QString &);
  };

worker->moveToThread(&workerThread);使得worker类中的槽doWork得以在线程中执行。使用这种方式很方便将一些耗时的工作丢给单独的工作线程来做,不同线程之间通过信号和槽进行关联协作。

猜你喜欢

转载自blog.csdn.net/qq_36413982/article/details/108906155