首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >字节一面:多个槽函数中有一个耗时,后续槽函数会被阻塞吗?

字节一面:多个槽函数中有一个耗时,后续槽函数会被阻塞吗?

作者头像
程序员的园
发布2025-02-20 13:20:19
发布2025-02-20 13:20:19
5570
举报

在之前的章节中,讲解过QT信号槽的连接类型,但是一个信号链接多个槽函数时,槽函数如何调用呢?是同步呢还是异步?如果是同步,那么多个槽函数中存在一个耗时的,其他槽函数会阻塞吗?

关于Qt信号槽的基础介绍和链接类型,请查看文章:某司客户端面试真题——Qt信号槽 槽函数调用方式

槽函数是同步调用还是异步调用,取决于信号与槽的连接类型。分别为:

  • Qt::DirectConnection:直接调用槽函数,属于同步调用。
  • Qt::QueuedConnection:将槽函数放入接收者对象的事件队列中,属于异步调用。
  • Qt::AutoConnection:当发送者和接收者在同一个线程时使用 Qt::DirectConnection(同步调用);当发送者和接收者不在同一线程时使用Qt::QueuedConnection(异步调用)。
  • Qt::BlockingQueuedConnection:将槽函数放入接收者对象的事件队列中,属于阻塞式异步调用,但会阻塞发送者线程,直到所有槽函数调用完毕。

如果一个信号以同步调用方式同时关联多个槽函数时,槽函数会按照链接顺序依次调用,当其中一个耗时比较长时,后续的槽函数会被阻塞,直到所有槽函数执行完毕。

如果以异步调用方式关联多个槽函数时,槽函数依然会依次调用,但是不会阻塞发送者线程,但接收者线程的执行顺序是按照连接顺序依次执行的。

如果以阻塞式异步调用方式关联多个槽函数时,槽函数依然会依次调用,但是会阻塞发送者线程,直到所有槽函数执行完毕为止。

例子 同步调用

例如,假设有一个信号 signal(),连接了 5 个槽函数 slot1()、slot2()、slot3()、slot4() 和 slot5(),其中 slot3() 是一个耗时的槽函数。当使用同步调用时,槽函数的执行顺序如下:

  1. slot1() 执行。
  2. slot2() 执行。
  3. slot3() 执行(耗时),此时会阻塞后续槽函数的执行。
  4. slot4()slot3() 完成后执行。
  5. slot5()slot4() 完成后执行。

此时,信号发出的线程会被完全阻塞,直到所有槽函数执行完毕。

异步调用

例如,假设信号连接了 5 个槽函数,其中 slot3() 是一个耗时的槽函数。在异步调用的情况下,槽函数会被放入事件队列,如下所示:

  1. slot1() 被放入事件队列。
  2. slot2() 被放入事件队列。
  3. slot3() 被放入事件队列(耗时)。
  4. slot4() 被放入事件队列。
  5. slot5() 被放入事件队列。

在接收者线程中,槽函数会依次执行:

  1. slot1() 执行。
  2. slot2() 执行。
  3. slot3() 执行(耗时,但不会阻塞信号发出的线程)。
  4. slot4()slot3() 完成后执行。
  5. slot5()slot4() 完成后执行。

这种机制的优势在于,信号发出的线程不会被阻塞,可以继续执行其他任务。只有接收者线程中的后续槽函数会受到耗时槽函数的影响。

建议

Qt 提供了灵活的信号与槽连接方式,使得开发者可以根据不同的需求选择合适的连接类型。

  • 同步调用:适用于信号和槽函数位于同一线程时,槽函数按顺序同步执行,但可能会造成阻塞,影响性能。
  • 异步调用:适用于多线程环境,槽函数异步执行,不会阻塞信号发出的线程。适合于耗时操作,能够保证主线程或其他线程的响应性。
  • 阻塞式异步调用:虽然槽函数异步执行,但信号发出的线程会被阻塞,直到槽函数执行完成。适用于需要等待接收者线程执行完某些操作的场景。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-02-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 例子 同步调用
    • 异步调用
  • 建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档