找回密码
 加入
搜索
查看: 2284|回复: 9

[网络通信] 多进程模拟多线路,子进程向母进程传递消息失败的问题[已解决]

[复制链接]
发表于 2019-7-6 22:40:19 | 显示全部楼层 |阅读模式
本帖最后由 xyx115 于 2019-7-17 15:43 编辑
#include "CoProc.au3"

#Region 主程序区域
#include <GUIConstants.au3>
$Form1 = GUICreate("Multiple File Download", 622, 500, 192, 125)
GUICtrlCreateLabel ( "CoProc接收子进程消息", 10, 10, Default, Default )
$Progress1 = GUICtrlCreateInput('', 10, 40, 600, 100)
GUICtrlCreateLabel ( "Atuoit3默认主进程接收消息", 10, 200, Default, Default )
$Progress2 = GUICtrlCreateInput('', 10, 230, 600, 100)

$iPidBig = _CoProc("Big")
GUISetState(@SW_SHOW)


_CoProcReciver("Reciver") ;注册Reciver()函数来接收子进程传递过来的消息
Autoit3_Atuo_Step()



While 1
        $msg = GUIGetMsg()
        Select
                Case $msg = $GUI_EVENT_CLOSE
                        ExitLoop
        EndSelect
WEnd

Exit

Func Reciver($vParameter)

        GUICtrlSetData($Progress1, $vParameter)

EndFunc   ;==>Reciver


Func Big()

        For $i = 1 To 10 Step 1
                _CoProcSend($gi_CoProcParent, '子进程的所要执行的代码,这是第' & $i & '次接收。')
                Sleep(1000)
        Next

EndFunc   ;==>Big


Func Autoit3_Atuo_Step()

        For $i = 1 To 10 Step 1
                GUICtrlSetData($Progress2, 'Atuoit3默认主进程接收消息,这是第' & $i & '次接收。')
                Sleep(1000)
        Next

EndFunc   ;==>Big



上面的代码是在论坛中搜索到的关于多进程模拟多线程的例子,用来做下载任务。在测试中发现使用模拟的方法下载,下载文件失败的概率远高于母进程下载。

现在打算用这个方法做多线程模拟网络测速。

发现除非写配置文件,才能把操作执行结果返回给母进程。否则不论怎么做,都不能传递变量出来。

还请各位高手帮忙看看,是不是我哪里弄错了。或者有更好的方法实现多线程、多进程,以及子母进程之间的通讯。

谢谢!


经afan指点,问题已解决。非常感谢。
问题原因:_CoProcSend不支持中文字符串,使用时需转换为二进制。
本文求助代码解决后如下:
#include "CoProc.au3"

#Region 主程序区域
#include <GUIConstants.au3>
$Form1 = GUICreate("Multiple File Download", 622, 500, 192, 125)
GUICtrlCreateLabel("CoProc接收子进程消息", 10, 10, Default, Default)
$Progress1 = GUICtrlCreateInput('', 10, 40, 600, 100)
GUICtrlCreateLabel("Atuoit3默认主进程接收消息", 10, 200, Default, Default)
$Progress2 = GUICtrlCreateInput('', 10, 230, 600, 100)

$iPidBig = _CoProc("Big")
GUISetState(@SW_SHOW)


_CoProcReciver("Reciver") ;注册Reciver()函数来接收子进程传递过来的消息
Autoit3_Atuo_Step()



While 1
        $msg = GUIGetMsg()
        Select
                Case $msg = $GUI_EVENT_CLOSE
                        ExitLoop
        EndSelect
WEnd

Exit

Func Reciver($vParameter)

        Local $Temp_Text = BinaryToString($vParameter)
        ;转换接收到的二进制为字符串
        GUICtrlSetData($Progress1, $Temp_Text)

EndFunc   ;==>Reciver


Func Big()
        
        Local $text[2] = ['子进程的所要执行的代码,这是第', '次接收消息']

        For $i = 1 To 10 Step 1
                Local $Temp_Text = StringToBinary($text[0] & $i & $text[1])
                ;转换需要发送的字符串为二进制
                _CoProcSend($gi_CoProcParent, $Temp_Text)
                Sleep(1000)
        Next

EndFunc   ;==>Big


Func Autoit3_Atuo_Step()

        For $i = 1 To 10 Step 1
                GUICtrlSetData($Progress2, 'Atuoit3默认主进程接收消息,这是第' & $i & '次接收。')
                Sleep(1000)
        Next

EndFunc   ;==>Autoit3_Atuo_Step











 楼主| 发表于 2019-7-8 13:58:03 | 显示全部楼层
有没有大神帮忙看一下这个问题。AU3不能多线程,有时候操作起来很麻烦。
发表于 2019-7-10 20:42:50 | 显示全部楼层
不会,帮顶了
发表于 2019-7-10 23:07:18 | 显示全部楼层
复制你的 _CoProcSend() 看看~

p.s, InetGet() 后台模式,支持多文件下载,不用多进程~

 楼主| 发表于 2019-7-16 17:41:36 | 显示全部楼层
本帖最后由 xyx115 于 2019-7-16 17:44 编辑
afan 发表于 2019-7-10 23:07
复制你的 _CoProcSend() 看看~

p.s, InetGet() 后台模式,支持多文件下载,不用多进程~
Func _CoProcSend($vProcess, $vParameter, $iTimeout = 500, $fAbortIfHung = True)
        Local $iPid, $hWndTarget, $MyData, $aTmp, $COPYDATA, $iFuFlags
        $iPid = ProcessExists($vProcess)
        If Not $iPid Then Return SetError(1, 0, False) ; Process not Found
        $hWndTarget = _ProcessGetWinList($vProcess, "", 16 + 2)
        If @error Or (Not $hWndTarget) Then Return SetError(2, 0, False) ; Window not found
        $MyData = DllStructCreate("char[" & StringLen($vParameter) + 1 & "]")
        $COPYDATA = DllStructCreate("ptr;dword;ptr")
        DllStructSetData($MyData, 1, $vParameter)
        DllStructSetData($COPYDATA, 1, 1)
        DllStructSetData($COPYDATA, 2, DllStructGetSize($MyData))
        DllStructSetData($COPYDATA, 3, DllStructGetPtr($MyData))
        If $fAbortIfHung Then
                $iFuFlags = 0x2 ; SMTO_ABORTIFHUNG
        Else
                $iFuFlags = 0x0 ; SMTO_NORMAL
        EndIf
        $aTmp = DllCall("user32.dll", "int", "SendMessageTimeout", "hwnd", $hWndTarget, "int", 0x4A _; WM_COPYDATA
                        , "int", 0, "ptr", DllStructGetPtr($COPYDATA), "int", $iFuFlags, "int", $iTimeout, "long*", 0)
        If @error Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
        If Not $aTmp[0] Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
        If $aTmp[7] <> 256 Then Return SetError(3, 0, False)
        $aTmp = DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWndTarget, "int", 0x400 + 0x64, "int", 0, "int", 0)
        If @error Then Return SetError(4, 0, False)
        If Not $aTmp[0] Then Return SetError(4, 0, False)
        Return True
EndFunc   ;==>_CoProcSend

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2019-7-17 11:15:02 | 显示全部楼层

一周前及时回应我还能帮你直接解决,现在过了这么久早已忘了当时的思路。
41行改一下看看结果:
_CoProcSend($gi_CoProcParent, $i)
其它的自己琢磨
 楼主| 发表于 2019-7-17 15:10:11 | 显示全部楼层
afan 发表于 2019-7-17 11:15
一周前及时回应我还能帮你直接解决,现在过了这么久早已忘了当时的思路。
41行改一下看看结果:
_CoPro ...

改为$i后,可以正常接收。经测试,不支持中文字符发送。谢谢!
 楼主| 发表于 2019-7-17 15:29:24 | 显示全部楼层
本帖最后由 xyx115 于 2019-7-17 15:31 编辑
afan 发表于 2019-7-17 11:15
一周前及时回应我还能帮你直接解决,现在过了这么久早已忘了当时的思路。
41行改一下看看结果:
_CoPro ...
#include "CoProc.au3"

#Region 主程序区域
#include <GUIConstants.au3>
$Form1 = GUICreate("Multiple File Download", 622, 500, 192, 125)
GUICtrlCreateLabel ( "CoProc接收子进程消息", 10, 10, Default, Default )
$Progress1 = GUICtrlCreateInput('', 10, 40, 600, 100)
GUICtrlCreateLabel ( "Atuoit3默认主进程接收消息", 10, 200, Default, Default )
$Progress2 = GUICtrlCreateInput('', 10, 230, 600, 100)

$iPidBig = _CoProc("Big")
GUISetState(@SW_SHOW)


_CoProcReciver("Reciver") ;注册Reciver()函数来接收子进程传递过来的消息
Autoit3_Atuo_Step()



While 1
        $msg = GUIGetMsg()
        Select
                Case $msg = $GUI_EVENT_CLOSE
                        ExitLoop
        EndSelect
WEnd

Exit

Func Reciver($vParameter)


        GUICtrlSetData($Progress1,BinaryToString($vParameter) )

EndFunc   ;==>Reciver


Func Big()
        
        Local $text[2] = ['子进程的所要执行的代码,这是第','次接收消息']

        For $i = 1 To 10 Step 1
                        
                _CoProcSend($gi_CoProcParent,StringToBinary($text[0]& $i & $text[1]) )
                Sleep(1000)
        Next

EndFunc   ;==>Big


Func Autoit3_Atuo_Step()

        For $i = 1 To 10 Step 1
                GUICtrlSetData($Progress2, 'Atuoit3默认主进程接收消息,这是第' & $i & '次接收。')
                Sleep(1000)
        Next

EndFunc   ;==>Big

经过提示,发送时字符串转换为二进制,接收后转换二进制为字符串,问题完美解决。谢谢!
发表于 2019-9-20 11:38:14 | 显示全部楼层
兄弟你的AutoIT是哪个版本?3.3.9.0测试这段代码时,发现子进程无法将消息发送至主进程GUI中。
发表于 2019-9-20 11:39:35 | 显示全部楼层
发现了,Coproc版本不同
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-16 09:23 , Processed in 0.080754 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表