QT 异步函数转为同步函数的方法

在QT中,一般推荐使用异步函数。除了异步函数的非阻塞特性外,QT的Signal/Slot特性在异步函数中可以得到充分的发挥。因此,在QT中,很多API的设计都是使用非阻塞的异步函数作为API,然后执行结果使用Signal返回。用户执行API后使用slot函数接收反馈结果。

但是在很多场景下,我们的确可能需要同步函数。也就是说函数在返回执行结果之前必须阻塞,调用函数后必须得到相应的执行结果。这时候,对于大量使用signal/slot的QT程序来说,经常需要将一个异步函数转变为同步函数。具体的转换做法如下。

例如一个异步的login函数:

void login(const QString& username, const QString& password);

返回值使用signal通知:

OnLoginStatusChanged();

下面就是这个异步函数的同步版本:

int loginSync(const QString& username, const QString& password)

{

int timeout = 30 * 1000; //超时时间设置

QTimer t;

  QEventLoop q;
  t.setSingleShot(true);
  connect(&t, SIGNAL(timeout()), &q, SLOT(quit()));  //异步调用超时退出
  connect(this, SIGNAL(OnLoginStatusChanged()), &q, SLOT(quit()));  //异步调用完成退出

  Login(username, password);   //调用异步函数
  t.start(timeout); 
  q.exec();
   
  //以下可以根据异步函数的返回结果进行进一步操作并返回函数结果。


}

需要注意的是,EventLoop的ProcessEvent实际上封装的是QAbstractEventDispatcher::processEvents。

QT帮助文件中有这样的描述:

An event dispatcher receives events from the window system and other sources. It then sends them to the

QCoreApplication orQApplication instance for processing and delivery. QAbstractEventDispatcher provides fine-grained control over event delivery.

也就是说,使用QAbstractEvent,或者说使用EventLoop,需要有QCoreApplication或者QApplication的存在。

对于GUI程序,这一点不是问题。问题在于对于很多consoleUI命令行程序,很多时候我们并不创建QCoreApplication或者QApplication对象。这样的场景下Eventloop自然无法正常使用。

因此,如果是在命令行中调用一个用这种方式封装的同步函数,必须有一个QCoreApplicaion或者QApplication对象存在。

原文地址:https://www.cnblogs.com/h2zZhou/p/9597199.html

时间: 2024-10-15 09:59:55

QT 异步函数转为同步函数的方法的相关文章

QT 异步函数和同步函数交换问题

同步函数与异步函数 依据微软的MSDN上的解说: (1)   同步函数:当一个函数是同步执行时,那么当该函数被调用时不会立即返回,直到该函数所要做的事情全都做完了才返回. (2)   异步函数:如果一个异步函数被调用时,该函数会立即返回尽管该函数规定的操作任务还没有完成. (3) 在一个线程中分别调用上述两种函数会对调用线程有何影响呢? 当一个线程调用一个同步函数时(例如:该函数用于完成写文件任务),如果该函数没有立即完成规定的操作,则该操作会导致该调用线程的挂起(将CPU的使用权交给系统,让系

JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this

JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程)把票陆陆续续的卖完了之后,我们要反思一下,这里面有没有安全隐患呢?在实际情况中,这种事情我们是必须要去考虑安全问题的,那我们模拟一下错误 package com.lgl.hellojava; import javax.security.auth.callback.TextInputCallback

es6的箭头函数转换为普通函数,以及将await/async函数转为普通函数

箭头函数转为普通函数: 1. 安装babel-preset-es2015  npm install babel-preset-es2015 --save-dev 2.在.babelrc文件夹中:  "presets": ["es2015"] await/async函数转为普通函数: 1. 安装babel-preset-stage-2 npm install babel-preset-stage-2  --save-dev 2.在.babelrc 文件中: "

.Net4.6 Task 异步OA现金盘平台出租函数 比 同步函数 慢5倍 踩坑经历

异步Task简单介绍本标题有点 哗众取宠OA现金盘平台出租QQ2952777280[话仙源码论坛]hxforum.com[木瓜源码论坛]papayabbs.com ,各位都别介意(不排除个人技术能力问题) -- 接下来:我将会用一个小Demo 把 本文思想阐述清楚. .Net 4.0 就有了 Task 函数 -- 异步编程模型 .Net 4.6 给 Task 增加了好几个 特别实用的方法,而且引入了 await async 语法糖 当然,这是非常不错的技术,奈何我有自己的线程队列封装,也就没有着

同步函数与异步函数

依据微软的MSDN上的解说: (1)   同步函数:当一个函数是同步执行时,那么当该函数被调用时不会立即返回,直到该函数所要做的事情全都做完了才返回. (2)   异步函数:如果一个异步函数被调用时,该函数会立即返回尽管该函数规定的操作任务还没有完成. (3) 在一个线程中分别调用上述两种函数会对调用线程有何影响呢? 当一个线程调用一个同步函数时(例如:该函数用于完成写文件任务),如果该函数没有立即完成规定的操作,则该操作会导致该调用线程的挂起(将CPU的使用权交给系统,让系统分配给其他线程使用

2015/01/23 – 不要对异步回调函数进行同步调用

绝对不能对异步回调函数(即使在数据已经就绪)进行同步调用. 如果对异步回调函数进行同步调用的话,处理顺序可能会与预期不符,可能带来意料之外的后果. 对异步回调函数进行同步调用,还可能导致栈溢出或异常处理错乱等问题. 如果想在将来某时刻调用异步回调函数的话,可以使用 setTimeout 等异步API. function onReady(fn) { var readyState = document.readyState; if (readyState == 'interactive' || re

多线程(同步代码块和同步函数)

线程安全问题 当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,    另一个线程参与进来执行.导致共享数据的错误. 解决办法:    对多条操作共享数据的语句,只能让一个线程都执行完.在执行过程中,其他线程不可以参与执行. Java对于多线程的安全问题提供了专业的解决方式.就是同步代码块. synchronized(对象){    需要被同步的代码}对象如同锁.持有锁的线程可以在同步中执行.没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁.

java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁

1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数封装的代码操作tickets,同步代码块中的锁我们可以指定.假设我们事先不知道同步函数用的是什么锁:如果在同步代码块中指定的某个锁(测试)和同步函数用的锁相同,就不会出现线程安全问题,如果锁不相同,就会发生线程安全问题. 看下面的代码:t1线程用的同步锁是obj,t2线程在操作同步函数的资源,假设不

多线程之同步代码块与同步函数

/*需求:买票分析:多个窗口卖票 是并发的,是多线程利用Runnable接口,传入一个对象,开启多线程 */class Ticket implements Runnable{ private int num=100; Object obj=new Object(); public void run(){ while(true){ synchronized(obj) { if(num>0) { System.out.println(num--+Thread.currentThread().getN