多进程模拟多线路,子进程向母进程传递消息失败的问题[已解决]
本帖最后由 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 = ['子进程的所要执行的代码,这是第', '次接收消息']
For $i = 1 To 10 Step 1
Local $Temp_Text = StringToBinary($text & $i & $text)
;转换需要发送的字符串为二进制
_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
有没有大神帮忙看一下这个问题。AU3不能多线程,有时候操作起来很麻烦。 不会,帮顶了 复制你的 _CoProcSend() 看看~
p.s, InetGet() 后台模式,支持多文件下载,不用多进程~
本帖最后由 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 Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
If $aTmp <> 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 Then Return SetError(4, 0, False)
Return True
EndFunc ;==>_CoProcSend xyx115 发表于 2019-7-16 17:41
一周前及时回应我还能帮你直接解决,现在过了这么久早已忘了当时的思路。
41行改一下看看结果:
_CoProcSend($gi_CoProcParent, $i)
其它的自己琢磨 afan 发表于 2019-7-17 11:15
一周前及时回应我还能帮你直接解决,现在过了这么久早已忘了当时的思路。
41行改一下看看结果:
_CoPro ...
改为$i后,可以正常接收。经测试,不支持中文字符发送。谢谢! 本帖最后由 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 = ['子进程的所要执行的代码,这是第','次接收消息']
For $i = 1 To 10 Step 1
_CoProcSend($gi_CoProcParent,StringToBinary($text& $i & $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 ;==>Big
经过提示,发送时字符串转换为二进制,接收后转换二进制为字符串,问题完美解决。谢谢! 兄弟你的AutoIT是哪个版本?3.3.9.0测试这段代码时,发现子进程无法将消息发送至主进程GUI中。 发现了,Coproc版本不同
页:
[1]