xyx115 发表于 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 = ['子进程的所要执行的代码,这是第', '次接收消息']

      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














xyx115 发表于 2019-7-8 13:58:03

有没有大神帮忙看一下这个问题。AU3不能多线程,有时候操作起来很麻烦。

ttexas 发表于 2019-7-10 20:42:50

不会,帮顶了

afan 发表于 2019-7-10 23:07:18

复制你的 _CoProcSend() 看看~

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

xyx115 发表于 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 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

afan 发表于 2019-7-17 11:15:02

xyx115 发表于 2019-7-16 17:41


一周前及时回应我还能帮你直接解决,现在过了这么久早已忘了当时的思路。
41行改一下看看结果:
_CoProcSend($gi_CoProcParent, $i)
其它的自己琢磨

xyx115 发表于 2019-7-17 15:10:11

afan 发表于 2019-7-17 11:15
一周前及时回应我还能帮你直接解决,现在过了这么久早已忘了当时的思路。
41行改一下看看结果:
_CoPro ...

改为$i后,可以正常接收。经测试,不支持中文字符发送。谢谢!

xyx115 发表于 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 = ['子进程的所要执行的代码,这是第','次接收消息']

      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




经过提示,发送时字符串转换为二进制,接收后转换二进制为字符串,问题完美解决。谢谢!

xowen 发表于 2019-9-20 11:38:14

兄弟你的AutoIT是哪个版本?3.3.9.0测试这段代码时,发现子进程无法将消息发送至主进程GUI中。

xowen 发表于 2019-9-20 11:39:35

发现了,Coproc版本不同
页: [1]
查看完整版本: 多进程模拟多线路,子进程向母进程传递消息失败的问题[已解决]