1、使用MYSQLI_ASYNC模式执行mysqli::query
2、获取异步查询结果:mysqli::reap_async_query
使用mysql异步查询,需要使用mysqlnd作为PHP的MySQL数据库驱动。
使用MySQL异步查询,因为需要给所有查询都创建一个新的连接,而MySQL服务端会为每个连接创建一个单独的线程进行处理,如果创建的线程过多,则会造成线程切换引起系统负载过高。Swoole中的异步MySQL其原理是通过MYSQLI_ASYNC模式查询,然后获取mysql连接的socket,加入到epoll事件循环中,当数据库返回结果时会回调指定函数,这个过程是完全异步非阻塞的。
在PHP-FPM处理HTTP请求时,有时会遇到一个请求需要进行多次MySQL查询(在报表类应用中比较常见)。通常我们会以串行方式查询:
$link = new mysqli()$rs1 = $link->query('SELECT * FROM table1')
while ($row = $rs1->fetch_row()) { ... }
$rs2 = $link->query('SELECT * FROM table2')
while ($row = $rs2->fetch_row()) { ... }
$rs3 = $link->query('SELECT * FROM table3')
while ($row = $rs3->fetch_row()) { ... }
串行查询方式有个缺点:在MySQL返回数据之前,PHP一直是处于空等的状态,不会继续往后执行。如果数据量大或者查询复杂,MySQL响应可能会比较慢,那么以串行方式查询会有一些延迟。给用户最直接的感受就是 Loading… 的圈圈一直打转。
那么有什么办法可以减少查询MySQL的时间?用多进程并行查询不行,因为PHP-FPM 中不允许用 pcntl_fork 一类的调用。
幸好还有 mysqlnd,mysqlnd提供了类似 stream_select 的机制(见 这篇文章) ,可以做到在单进程中对MySQL并行查询。这主要运用了mysqli_poll 和 reap_async_query 两个函数。
还是通过例子来介绍MySQL并行查询的实施方法。假设要并行地向MySQL发出10个查询,最基本的代码应该是这样的:
1. $links = []2. for ($i = 0 $i !== 10 $i++) {
3. $links[$i] = new mysqli('127.0.0.1', 'user', 'password', 'db1')
4. $links[$i]->query('SELECT SLEEP(1)', MYSQLI_ASYNC)
5. }
6. $allResult = []
7. while (!empty($links)) {
8. $reads = $links
9. $errors = $reject = []
10. if (!mysqli_poll($reads, $errors, $reject, null)) {
11. continue
12. }
13. foreach ($reads as $read) {
14. $idx = array_search($read, $links, true)
15. $allResult[$idx] = []
16. $result = $read->reap_async_query()
17. while ($row = $result->fetch_row()) {
18. $allResult[$idx][] = $row
19. }
20. $read->close()
21. unset($links[$idx])
22. }
23. }
解释下这段代码的含义:
2~5行,同时发起10个MySQL连接,并发出查询
注意query() 的第二个参数带上了 MYSQLI_ASYNC 表示非阻塞查询
10行,使用mysqli_poll 轮询10个连接的查询有无返回
mysqli_poll 的第一个参数$reads是个数组,包含需要轮询那些连接。mysqli_poll 执行完后,会改写$reads,改写后$reads包含的是那些已经有数据返回连接。
mysqli_poll的第四个参数,控制的是轮询的等待时间,单位是“秒”。如果像本例当中设置为null,那么mysqli_poll轮询是阻塞的:只有监听的连接中,任意一个连接有数据返回了,mysqli_poll才会返回。如果等待时间设置为0,那么每次执行mysqli_poll会立即返回,外层的while会频繁循环。
第11~19行,遍历已经有数据返回的连接
reap_async_query和普通query一样,返回的是mysqli_result,可以一行行fetch数据
20~21行,对于已经获得了数据的连接,下次mysqli_poll就不需要再轮询这个连接了,所以关闭连接,并从$links数组删除这个连接
当所有的连接都返回了数据,$links数组空了,while循环也就终止了。
使用并行查询的方式,可以大大缩短处理HTTP请求的时间,假设本例中的10个SQL查询,每个需要执行1秒。因为是并行,处理所有的查询,也只需要1秒左右。
涂色命令语言是无障碍由于Auto.js目前的API都是同步的,要在屏幕中搜索某张图色或者某个控件时,必须无限循环查找,这实际上非常耗电。由于Rhino的限制,Auto.js无法直接提供异步API,这让Auto.js的脚本天生有一些缺陷。为了解决这些问题,Auto.js Pro 8.0.0-3引入了两个新的API,来尽量减少图色模块和控件模块使用时的耗电。
图色模块的耗电优化
requestScreenCapture(options)
options {Object}
async {Boolean} 是否以异步事件的形式提供截图
width {Number} 截图宽度
height {Number}} 截图高度
orientation {String} 屏幕方向,"landscape"为横屏,"portrai"为竖屏,"auto"为自动
请求截图权限的参数中,增加了async的参数,这个参数运行我们以异步的方式,来获取屏幕截图。在以前,我们通过captureScreen()函数来获取截图,并无限循环地寻找目标图片,比如:
// 请求截图权限
requestScreenCapture()
// 读取目标图片
let target = $images.read("./test.png")
while (true) {
// 获取屏幕截图
let capture = $images.captureScreen()
// 找图
let pos = $images.findImage(capture, target)
// 打印
console.log(pos)
}
而使用async参数后,我们可以在"screen_capture"事件中获取到图片,例如:
// 请求截图权限, 注意参数 async: true
requestScreenCapture({async: true})
// 监听屏幕截图
$images.on("screen_capture", capture =>{
// 找图
let pos = $images.findImage(capture, target)
// 打印
console.log(pos)
})
使用这样的方式,我们可以只在屏幕刷新时通过事件screen_capture唤醒代码,获取到最新的屏幕截图,并寻找目标图片。
实测在普通软件界面的找图中,CPU使用率减少了75%左右。
无障碍功能的耗电优化
与找图找色类似,在以前,Auto.js也一直只能通过无限循环去判断当前界面、寻找控件,这实际上对省电优化十分不友好。在Pro 8.0.0-3版本,我们引入了监听无障碍事件的API。
auto.registerEvents(events)
events {Array} 要监听的事件数组
返回 {EventEmitter}
auto.registerEvent(event, callback)
event {String} 要监听的事件
callback {Function} 事件回调
返回 {EventEmitter}
以上两个函数用于监听一个或多个无障碍事件。所谓无障碍事件,即(其他软件)窗口发送变化、控件发送变化时的事件,包括:
view_clicked 控件被点击
view_long_clicked 控件被长按点击
view_selected 控件被选中
view_focused 控件成为焦点
view_text_changed 控件文本改变
view_scrolled 控件被滑动
window_state_changed 窗口状态变化
window_content_changed 窗口内容变化
window_changed 屏幕上显示窗口的变化(增加,删除,子窗口变化等)
notification_state_changed 通知状态变化
例如,我们要监听Auto.js的打开,可以用以下代码监听:
// 监听窗口变化
auto.registerEvent('windows_changed', e =>{
// 判断是否有新窗口打开
if (e.windowChanges.indexOf('add') >= 0) {
// 获取新窗口的id
let wid = e.windowId
// 遍历窗口,获取新窗口
let window = auto.windows.filter(w =>w.id == wid)
// 判断新窗口是Auto.js
if (window.length >= 0 &&window[0].title == 'Auto.js') {
toast("Auto.js被打开了!")
}
}
})
点击阅读全文
打开CSDN APP,看更多技术内容
autojs手机端截图取色助手.apk
青咖脚本autojs多功能截图取色识别颜色工具青咖网auto.js免root引流脚本专用找图找色工具分享
zulu8.33.0.1-jdk8.0.192-win_x64.msi
zulu8.33.0.1-jdk8.0.192-win_x64.msi
最新发布 AUTOJS】9.0去限制找控件
autojs去限制
继续访问
MySql.Data.dll8.0类库
用于mysql8.0版本的MySql.Data.dll类库,直接引用使用
用于mysql8.0版本的MySql.Data.dll类库,直接引用使用
用于mysql8.0版本的MySql.Data.dll类库,直接引用使用
app_autojs_4_1_1.zip
1) autojs 安装 apk 版本 4_1_1 2) 包含 autojs 本身安装apk 和 打包 脚本成apk 文件的插件
Auto.JS函数requestScreenCapture()采坑小结一requestScreenCapture()不能多次调用
今天写了一个脚本,遇到些问题与大家分享。脚本需要找图代码如下(注意标识位置) function zhaotu(tpname,regx,regy ,regwidth,regheight){ requestScreenCapture()//注意这个位置 pd=nullvar tp = images.read(tpname) toast("tupian:"+tp)sleep(3000)pd =findImage( cap
继续访问
Auto.js实现自动授权截屏权限
写在前面: 本文章记录自己在开发过程中,遇到的基础问题,也同样便于在以后的开发中获得便利。 如果你是初学Auto.js开发,建议可以读这篇文章Auto.js入门【超基础】,该文章是我入门时拜读的作品,整体感觉很好,基本内容都有所讲到,完全可以适合新手做出一些简单的脚本自用。 一、开发文档 在开发文档中该方法也提到,有些系统是没有保持始终允许的选项的,题主也是遇到了这个问题,因为写的脚本时定时运行的,不可能自己再手动授权,所以自己写了一个能够自动授权方法,还有很多不足的地方,希望大家可以斧正。 二、进阶方法
继续访问
Android 9.0 Auto及m4 core倒车逻辑--基于imx8qm
新板子car版本android系统收不到m4发送的资源释放消息,屏不亮,先分析一下逻辑关系。 上图就是car版本AP核和M41核之间的倒车逻辑。 阶段1 系统启动完毕 mek_8q.mk 63: $(IMX_DEVICE_PATH)/init_car_m4.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.car_additional.rc 68: $(IMX_DEVICE_PATH)/init_car_no_m4.rc:$(TARGET_COPY_O.
继续访问
【Auto.js】[系统Intent]_系统设置页面的相关intent跳转
收集了一些系统设置界面的Intent跳转,只收集了不传值,可直接调用一些参数 var intent = new Intent()// vpnIntent.setAction("android.net.vpn.SETTINGS")intent.setAction("android.settings.ACCESSIBILITY_SETTINGS")//辅助功能 intent.setAction("android.settings.ADD_ACCOUNT_SETTINGS")//添加账户 in
继续访问
Auto.js找图找色常用功能
1. 颜色的表示方法 颜色表示方式一:"#AARRGGBB",需要表示透明度的时候用这种方法。 颜色表示方式二:"#RRGGBB",不需要表示透明度的时候用这种方法。 AA 是Alpha通道(透明度)的值; RR 是R通道(红色)的值; GG 是G通道(绿色)的值; BB 是B通道(蓝色)的值; 2. 颜色的转换方法 1. 返回颜色值的字符串; 2. 返回颜色的整数值; .....................
继续访问
Auto.js Pro_Pro 7.0.4-1.apk
兼容性说明 不支持安卓10以上和华为手机调试运行,推荐在小米手机上调试运行。 但是打包的脚本不分手机型号都能运行。
auto.js脚本大全
收集2000余个脚本
autojs-clipboard
本仓库主要为了, 方便手机和电脑剪贴板, 在局域网同步 同步原理 手机autojs运行mobile.js, 监听到剪贴板变化, 就发送http请求 在vscode中, 按 ctrl + shift + p, 输入clip, 点击autojs: Clipboard synchronization 剪贴板同步, 开启服务 服务开启后, vscode会监听7101端口的请求, 并提取get请求中的clipboard的值 用clipboardy设置剪贴板内容 牙叔出品, mobile.js用抠脚代码改的.
热门推荐 mysql8.0.25安装配置教程(windows 64位)最详细
目录1.官网下载MySQL2.配置初始化文件my.ini3.初始化MySQL4.安装mysql服务并启动+修改密码5.配置环境变量6.部分疑难杂病7.使用连接工具连接mysql 1.官网下载MySQL 下载Mysql点击下载mysql. 下载完成后解压到某一个文件夹(记住这个路径,一会要用到) 2.配置初始化文件my.ini 在根目录下创建一个txt文件,名字叫my,文件后缀为ini 之后复制下面这个代码放在文件下 (新解压的文件没有my.ini文件,需自行创建) 以下代码除安装目录和数据的存放目录需修
继续访问
auto js实现自动截屏
// 请求允许自动录屏 //请求截图 if(!requestScreenCapture()){ toast("请求截图失败")exit()} 连续截图 //连续截图10张图片(间隔1秒)并保存到存储卡目录 for(var i = 0i <10i++){ captureScreen("/sdcard/img" + i + ".png")...
继续访问
AutojsPro 华为手机设置
Autojs 华为手机 设置
继续访问
Auto.js Pro使用Intent跳转详细介绍
说明:此方法需要手机root。如果没有root也想使用需要用adb,给手机app一些权限才可以(此方法没测试,我直接root了。权限看我另外一篇文章)autojs无root自动无障碍启动------华为_shuishen49的博客-CSDN博客 以下是我抓的包 代码需要这么写 其实最主要的是这个表要传数据给app,必须先清楚。我也研究了好一会。 extras: {//前面是key,后面是值,class是数据类型不管他。js自己能识别。 key_router_time:
继续访问
对C语言语法复习与关键字auto,register的深度理解,看完保证你惊呼“妈妈有挂!”
首先是最宽宏大量的关键词 auto 先普及几个简单的c语言概念 便于理解 在刚开始学习c语言时 ,我们都会学习打印“helloworld”,如下代码 我们思考一下电脑是如何去编译出代码并且打印helloworld的 首先代码运行以后会通过编译器对代码进行编译与链接,其中编译分为3步,先进行预编译,后进行编译,然后进行汇编,形成。.obj文件 。obj文件再进行链接形成了.exe文件,也就是我们的应用程序。 在windows系统中双击exe文件,运行程序,会将程序加载到内存中(对,就是电..
继续访问
火山pc实现找图找色模块
利用增强位图 *** 作模块的取坐标颜色实现找图、找色 没多少技术含量,高手勿喷 一、首先要引用增强位图类 二、引用风的模块(下载地址:火山pc找图色例子 模块-利快云源码下载 (lkuaiy.com)) 三、使用图色区域找图这个命令就可以实现图色的自动化
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)