AHK_L版调用H版dll实现多线程函数

多线程与单线程的区别:

单线程顺序执行:ABCDEFG,HIJKLMN
单线程异步执行:ABC,KLMN,EFGHI,错开执行避免I/O之类的长时间等待卡住线程【WinWait】
多线程:一个进程内可有多个线程ABCDEFG同时执行互不干扰
多进程:创建多个进程ABCDEFG并互相通信,来达到仿多线程的效果。

 

通过调用AHK_V1_H版的方式,实现多线程的函数库。

H版dll只有主进程对子线程的控制,没有子线程对主进程的控制。

想实现子线程对主进程的汇报或控制,可以参考多进程函数库的WM_COPYDATA通信方法

多进程函数库的链接:https://www.autoahk.com/archives/38591

 /*
═══════════════════════════════════════════════════════════

                                        AHK_L版调用H版dll实现多线程方法

    详见H版帮助文档:https://hotkeyit.github.io/v1/docs/commands/AhkThread.htm
    以下为简单演示:
      ahk.textdll(代码内容, 线程编号, 可传参) ; 开启一个新线程
      ahk.Terminate(线程编号) ; 结束指定线程 【ahk.textdll("", 1)也可结束】
    更多比如线程重启、暂停、在线状态,调用线程中的函数,给线程的变量赋值,检查
    线程中变量的值,指定线程跳转标签等解释请查看Lib\AhkLThread.ahk

═══════════════════════════════════════════════════════════
*/
#Include <AhkLThread>

; 以下为创建新线程多行写法
s=
(` %
; #NoTrayIcon ; 关闭新线程托盘图标显示
Loop {
    Sleep 10
    MouseGetPos, x, y
    ToolTip % A_Args[1] A_Index, x+10, y-70
}
Return

MyFunc(可传参, 可传参2) {
    MsgBox, , 1号线程对话框, % "传参1内容为:" 可传参 "`n传参2内容为:" 可传参2
}

标签1:
MsgBox, , 1号线程对话框,  仅标签跳转演示`n`nF4给线程赋值:%var%
Return
)
ahk.textdll(s, 1, "传参:1号线程持续运算-")

; 以下为创建新线程单行写法
ahk.textdll("Loop {`nSleep 10`nMouseGetPos, x, y`nToolTip % A_Args[1] A_Index, x+10, y-30`n}", 2, "传参:2号线程持续运算-")

; 调用外部脚本文件的写法
; ahk.dll("外部脚本文件名.ahk", 3, "传参运行线程333")

MsgBox, , 主进程对话框, 点击确定后主进程将结束,`n`n连带所有新线程也会跟着结束。
ExitApp

; F1:对1号线程暂停/开启的切换
F1::
if (onoff := !onoff)
    ahk.Pause(1)
  else
    ahk.Pause(1, "Off")
Return

; F2:在1号线程里进行传参并调用函数【归属于1号线程】
F2::ahk.PostFunction(1, "MyFunc", "Hello World!", "第二个参数")

 ; F3:在1号线程里跳转标签运行【归属于1号线程】
F3::ahk.Label(1, "标签1", 1) ; 仅跳转不赋值

F4::
ahk.Assign(1, "var", "123456") ; 给1号线程的"var"变量赋值
MsgBox, , 主进程对话框, % "给1号线程的 var 变量赋值为:" ahk.Getvar(1, "var") ; 主进程查看1号线程的变量内容
Return

AhkLThread.ahk

; 更多解释详见H版帮助文档:https://hotkeyit.github.io/v1/docs/commands/AhkThread.htm

Class ahk {

    ; 以脚本文件来新建线程:ahk.dll("外部脚本文件名.ahk", 1)
    dll(脚本路径, 线程编号, 传参:="") {
        ahk.新建线程文件(线程编号)
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkdll", "Str", 脚本路径, "Str", , "Str", 传参, "Ptr")
        Return Rtn
    }

    ; 以脚本内容新建线程:ahk.textdll("MsgBox Hello World!", 1)
    textdll(脚本内容, 线程编号, 传参:="") {
        ahk.新建线程文件(线程编号)
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahktextdll", "Str", 脚本内容, "Str", , "Str", 传参, "CDecl")
        Return Rtn
    }

    ; 调用线程中的函数【SendMessage】:ahk.Function(1, "MyFunc", "Hello World!")
    Function(线程编号, FuncName, Arg1:="", Arg2:="", Arg3:="", Arg4:="", Arg5:="", Arg6:="", Arg7:="", Arg8:="", Arg9:="", Arg10:="") {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkFunction","Str",FuncName,"Str",Arg1,"Str",Arg2,"Str",Arg3,"Str",Arg4,"Str",Arg5,"Str",Arg6,"Str",Arg7,"Str",Arg8,"Str",Arg9,"Str",Arg10,"CDecl Str")
        Return Rtn
    }

    ; 调用线程中的函数【PostMessage不等待函数返回】:ahk.PostFunction(1, "MyFunc", "Hello World!")
    PostFunction(线程编号, FuncName, Arg1:="", Arg2:="", Arg3:="", Arg4:="", Arg5:="", Arg6:="", Arg7:="", Arg8:="", Arg9:="", Arg10:="") {
        DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkPostFunction","Str",FuncName,"Str",Arg1,"Str",Arg2,"Str",Arg3,"Str",Arg4,"Str",Arg5,"Str",Arg6,"Str",Arg7,"Str",Arg8,"Str",Arg9,"Str",Arg10,"CDecl Str")
    }

    ; 指定线程跳转标签【1=不等待返回,0=默认等待】ahk.Label(1, "MyLabel", 1)
    Label(线程编号, 标签名, 等待:=0) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkLabel", "Str", 标签名, "UInt", 等待,"CDecl Int")
        Return Rtn
    }

    ; 给线程的变量赋值:ahk.Assign(1, "var", "123456")
    Assign(线程编号, Var, Value:="") {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkassign", "Str", Var, "Str", Value, "CDecl")
        Return Rtn
    }

    ; 检查线程中变量的值:ahk.Getvar(1, "var")
    Getvar(线程编号, Var, GetVar:=0) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkgetvar", "Str", Var, "UInt", GetVar, "CDecl Str")
        Return Rtn
    }

    ; 查看线程运行状态:MsgBox % ahk.Ready(1)
    Ready(线程编号) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkReady")
        Return Rtn
    }

    ; 暂停指定线程:ahk.Pause(1, "Off")
    Pause(线程编号, 开关:="On") {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkPause", "Str", 开关, "Int")
        Return Rtn
    }

    ; 重启指定线程:ahk.Reload(1)
    Reload(线程编号, TimeOut:=0) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkReload", "Int", TimeOut, "Int")
        Return Rtn
    }

    ; 结束指定线程:ahk.Terminate(1)
    Terminate(线程编号, Timeout:=0) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkTerminate", "Int", Timeout, "Int")
        Return Rtn
    }

    ; https://hotkeyit.github.io/v1/docs/commands/ahkExec.htm
    Exec(脚本内容, 线程编号) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkExec", "Str", 脚本内容, "CDecl")
        Return Rtn
    }

    ; https://hotkeyit.github.io/v1/docs/commands/addScript.htm
    addScript(脚本内容, 线程编号, 等待执行:=1) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\addScript", "Str", 脚本内容, "Int", 等待执行, "CDecl")
        Return Rtn
    }

    ; https://hotkeyit.github.io/v1/docs/commands/addFile.htm
    addFile(脚本路径, 线程编号, 等待执行:=1) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\addFile", "Str", 脚本路径, "Int", 等待执行, "Cdecl")
        Return Rtn
    }

    ; https://hotkeyit.github.io/v1/docs/commands/ahkFindFunc.htm
    FindFunc(函数名称, 线程编号) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkFindFunc", "Str", 函数名称, "CDecl PTR")
        Return Rtn
    }

    ; https://hotkeyit.github.io/v1/docs/commands/ahkFindLabel.htm
    FindLabel(标签名称, 线程编号) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkFindLabel", "Str", 标签名称, "CDecl PTR")
        Return Rtn
    }

    ; https://hotkeyit.github.io/v1/docs/commands/ahkExecuteLine.htm
    ExecuteLine(线程指针, 线程编号, 模式:=0, 等待:=0) {
        Rtn := DllCall("AutoHotkeyU" this.bit "H" 线程编号 ".dll\ahkExecuteLine", "Ptr", 线程指针, "UInt", 模式, "UInt", 等待, "PTR")
        Return Rtn
    }

    新建线程文件(线程编号) {
        FileCreateDir, %A_Temp%\AHKLThread
        this.bit := A_PtrSize=4 ? 32 : 64
        if !FileExist(A_Temp "\AHKLThread\AutoHotkeyU" this.bit "H" 线程编号 ".dll")
            FileCopy, % A_ScriptDir "\Lib\AutoHotkeyU" this.bit "H.dll", % A_Temp "\AHKLThread\AutoHotkeyU" this.bit "H" 线程编号 ".dll"
        DllCall("LoadLibrary", "Str", A_Temp "\AHKLThread\AutoHotkeyU" this.bit "H" 线程编号 ".dll")
    }

} ; // Class End

以下是带H版dll的打包下载,如有dll更新可自行替换更新

蓝奏云下载

百度云下载

给TA捐赠
共{{data.count}}人
人已捐赠
其他教程

AHK调用opencv(十三)图像的几何变换 – ahk_v2_beta3

2022-3-27 14:47:28

其他

一个语言和技术之外的问题

2022-3-30 11:11:11

14 条回复 A文章作者 M管理员
  1. AHK中文社区
    1河许人给您打赏了¥4
  2. AHK中文社区

    库文件也放进来的好

  3. Gan

    请求大佬可以说明一下如何任务分派,以及ahk.textdll(代码内容, 线程编号, 可传参)里面代码内容,是否是原来单线程的完整代码?

  4. vswfuequ1

    各个线程怎么共享变量、共享函数

  5. vswfuequ1

    怎么更改AutoHotkeyU64H.dll的位置,打包成exe后必须有这个

  6. 231223

    请问发布的L版多线程 不能用在FindText吗?不知道怎才能使用

    • dbgba

      把FindText类库里的local替换成 ; local 也就是注释掉local

    • 231223

      FindText 一次性全部都替换成了; local 但是还不能使用

    • 231223

      写的那一行FindText没有问题,不知道问题 出在哪里

    • 231223

      解决了,请问但是很容易掉,运行几次就会退出,应该怎么解决

  7. 199596

    感谢大佬

  8. 55330267

    感谢大佬

个人中心
购物车
优惠劵
有新私信 私信列表
搜索