Qt+Creator快速入门-----第十九章(进程和线程)学习总结

进程

Qt的QProcess类用来启动一个外部程序并与其进行通信。

要启动一个进程,可以使用start()函数,然后将程序名称和运行这个程序所要使用的命令行参数作为该函数的参数。

执行完start()函数后,QProcess进入Starting状态,当程序已经运行后,QProcess就会进入Running状态started()信号。

实现进程间通信IPC(Inter-Process Communication)

  1. TCP/IP
  2. 共享内存:QSharedMemory是跨平台的共享内存类,提供了访问操作系统共享内存的实现。
  3. D-Bus:它将Qt的信号和槽机制扩展到IPC层面,允许一个进程发射的信号关联到另一个进程的槽上,可以查看帮助D-Bus关键字。
  4. QProcess
  5. 会话管理
  6. QLocalSocket类提供了一个本地套接字,在Windows上它是一个有名管道,在Unix上他是一个本地域套接字

线程

多线程编程可以有效解决在不冻结一个应用程序用户界面的情况下执行一个耗时操作的问题。可以通过Thread Support in Qt查看。

QThread类提供了与平台无关的线程。从run()函数开始执行,默认的run()通过调用exec()来启动事件循环,并在线程内运行一个Qt事件循环,使它能够关联其他线程中的信号到本线程的槽上。要创建一个线程,需要子类实例化QThread,并重新实现run()函数。注意,在线程中无法使用任何界面部件类。

QThread会在开始、结束和终止时发射start()、finished() 和terminated()等信号,可以使用isFinished()和isRunning()来查询线程的状态。可以使用wait()来阻塞,直到线程结束。

 以下案例创建一个线程执行后台任务:

 

class MyThread : public QThread
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = nullptr);
    void stop();

signals:

protected:
    void run();
private:
    volatile bool stopflag;

};
MyThread::MyThread(QObject *parent) : QThread(parent)
{
    stopflag=false;
}

void MyThread::run()
{
    qreal i=0;
    while(!stopflag)
    {
        qDebug()<<QString("in MyThread:%1").arg(i);
        msleep(1000);
        i++;
    }
    stopflag=false;
}
void MyThread::stop()
{
    stopflag=true;
}
void Widget::on_startButton_clicked()
{
    myThread.start();
   
    ui->startButton->setEnabled(false);
    ui->stopButton->setEnabled(true);
}

void Widget::on_stopButton_clicked()
{
    if(myThread.isRunning())
    {
        myThread.stop();
        ui->startButton->setEnabled(true);
        ui->stopButton->setEnabled(false);
    }
}

void Widget::closeEvent(QCloseEvent *event)
{
    if(myThread.isRunning())
    {
        myThread.stop();
        myThread.wait(1000);
    }
}
View Code

 

同步线程的几种方式:

  1. QMutex提供一个互斥锁(mutex),用于对共享数据的访问进行保护。
  2. QReadWriteLock读写锁
  3. QSemaphore信号量,用来保护一定数量的相同资源
  4. QWaitCondition条件变量

可重入(reentrant)和线程安全(thread-safe)

1. 一个线程安全的函数可以同时被多个线程调用,即使是它们使用了共享数据,因为该共享数据的所有实例都被序列化了。

2. 一个可重入的函数也可以被多个线程调用,但是只能是在每个调用使用自己的数据的情况下。

因此,一个线程安全的函数总是可重入的,但是一个可重入的函数不总是线程安全的。

QT支持几种信号和槽的关联类型

  1. Auto Connection
  2. Direct Connection :发送者和接收者在不同线程是使用它不安全
  3. Queued Connection
  4. Blocking Queued Connection
  5. Uniqueue Connection

 

posted @ 2022-02-07 21:42  HelloWorld庄先生  阅读(259)  评论(0编辑  收藏  举报