Qt------多线程以及线程同信号与槽的关系

 

1.相关定义

1.1多线程

即分时利用CPU,宏观上让所有线程一起执行 ,也叫并发

  • QThreadPool线程池
  • QMutex互斥锁:保证任意时刻只有一个线程进行访问

1.2线程五种状态

  1. 创建:生成线程对象,没有调用该对象的Start方法
  2. 就绪 :调用了该对象的Start方法,但是线程调度程序没有把该线程设置为当前线程,此时处于就绪状态
  3. 运行 :线程调度程序将就绪状态的线程设置为当前线程,此时处于运行状态,开始执行run函数里面的内容
  4. 阻塞 :线程正在运行的时候,被暂停(通常是为了等待某项资源就绪,之后再继续运行) sleep suspend wait 
  5. 死亡:run()方法结束,或者调用stop之后,线程死亡,无法使用start再次使其进入就绪状态   

1.3多线程配合信号和槽:

连接时第五个参数,为线程间信号和槽的通讯方法

  1. 直接连接,槽运行在发出信号的线程 DirectConnection
  2. 队列连接,槽运行在接收信号的生存线程中,依赖于事件循环 QueuedConnection
  3. 自动选择,根据发出信号线程和信号接收对象的生存线程,自动选择直接连接和 队列连接

2.使用

2.1使用concurrent 高级线程API

#include <QtConcurrent>//在pro文件中添加concurrent
// threadPool.waitPorDone(); //等待所有的线程结束
QtConcurrent::run([=](){ //中括号用于捕获
 //实际运行在子线程中
 qDebug()<<"QtConcurrent:"<<QThread::currentThread();
 QFile file(filepath); //创建文件路径
 file.open(QIODevice::WriteOnly);
 file.write(data);
 file.waitForBytesWritten(30*1000);
});
QtConcurrent::run(&threadPool,[&](){ //使用&捕获锁
   //操作之前,先锁住---保证当前线程在访问当中,其他线程等着
   mutex.lock();

   //操作之后,就进行解锁
    mutex.unlock();        
});
Sender sender; //信号的发送方(生存线程即主线程)
QtConcurrent::run([&](){
   Receive receiver; //接收方是自己开启的一个子线程
   //转移线程操作
   receiver.moveToThread(qApp->thread());//由线程转移到主线程
   QObject::connect(&sender,&Sender::mySignal,&receiver,&Receive::onReceive); //创建连接默认采用自动连接选择直接连接可以省略不写但是必须注
  // 采用直接连接的方式:槽运行发出的信号的线程,这里发出信号的线程就是主线程,机槽运行在主线程中
 QObject::connect(&sender,&Sender::mySignal,&receiver,&Receive::onReceive,Qt::DirectConnection);//直接连接与上面连接方式是一致的
  //采用队列的方式联机,槽运行在接收信号对象的生存线程,依赖于事件循环,槽运行在子线程中
  QObject::connect(&sender,&Sender::mySignal,&receiver,&Receive::onReceive,Qt::QueuedConnection);//队列连接

  QEventLoop eventLoop;
  eventLoop.exec();//启动事件循环--=-直连不需要事件循环,如果是队列连接需要进行事件循环
});
   QThread::sleep(1);
   emit sender.mySignal(); //发射信号
   return a.exec();

3.QThread类主要接口

  • bool isFinished() 线程是否结束
  • bool isRunning 线程是否正在运行
  • Priority priority 返回线程的优先级
  • void setPriority(Priority priority) 设置线程的优先级
  • void exit(int returnCode=0)退出线程的事件循环,退出码为returnCode ,0表示成功退出,否则表示有错误
  • bool wait(unsigned long time) 阻止线程执行,直到线程结束(从run()函数返回),或等待时间超过time毫秒
  • void quit 退出线程的事件循环,并返回代码0,等效于exit(0)

注意:

1.主线程与子线程占用不同的内存空间

2.避免死锁:lock和unlock配对使用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Qt中,信号是一种用于对象间通信的机制,可以在多线程环境下使用。通过信号,一个对象可以发射信号,而其他对象可以连接到这个信号并执行相应的函数。 在多线程中使用信号时,需要注意以下几点: 1. 当信号的发送与对象的函数的执行在不同线程中时,可能会产生临界资源的竞争问题。因此,需要使用线程间同步机制来保护共享资源的访问。 2. 在Qt中,QThread继承自QObject,因此可以使用发射信号和定义函数的能力。QThread默认声明了几个关键信号: - started():线程开始运行时发射的信号。 - finished():线程完成运行时发射的信号。 - terminated():线程被异常终止时发射的信号。 下面是一个示例代码,演示了在Qt中如何使用信号进行多线程通信: ```cpp #include <QThread> #include <QDebug> // 自定义线程类 class MyThread : public QThread { Q_OBJECT public: void run() override { qDebug() << "Thread started"; // 执行一些耗时操作 // ... // 发射信号 emit mySignal("Hello from thread"); qDebug() << "Thread finished"; } signals: void mySignal(const QString& message); }; // 自定义函数 class MyObject : public QObject { Q_OBJECT public slots: void mySlot(const QString& message) { qDebug() << "Received message:" << message; } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); MyThread thread; MyObject object; // 连接信号 QObject::connect(&thread, SIGNAL(mySignal(QString)), &object, SLOT(mySlot(QString))); // 启动线程 thread.start(); return a.exec(); } ``` 这段代码中,我们创建了一个自定义的线程类`MyThread`,其中重写了`run()`函数,在函数中执行一些耗时操作,并发射了一个自定义的信号`mySignal`。然后,我们创建了一个自定义的对象`MyObject`,其中定义了一个函数`mySlot`,用于接收信号并处理。在`main()`函数中,我们创建了线程对象和对象对象,并使用`QObject::connect()`函数将信号连接起来。最后,启动线程并运行Qt事件循环。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值