找回密码  加入

QQ登录

只需一步,快速开始

AUTOIT CN

搜索
查看: 413|回复: 9

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

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

  1. #include "CoProc.au3"

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

  9. $iPidBig = _CoProc("Big")
  10. GUISetState(@SW_SHOW)


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



  13. While 1
  14.         $msg = GUIGetMsg()
  15.         Select
  16.                 Case $msg = $GUI_EVENT_CLOSE
  17.                         ExitLoop
  18.         EndSelect
  19. WEnd

  20. Exit

  21. Func Reciver($vParameter)

  22.         GUICtrlSetData($Progress1, $vParameter)

  23. EndFunc   ;==>Reciver


  24. Func Big()

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

  29. EndFunc   ;==>Big


  30. Func Autoit3_Atuo_Step()

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

  35. EndFunc   ;==>Big
复制代码




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

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

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

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

谢谢!


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



  1. #include "CoProc.au3"

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

  9. $iPidBig = _CoProc("Big")
  10. GUISetState(@SW_SHOW)


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



  13. While 1
  14.         $msg = GUIGetMsg()
  15.         Select
  16.                 Case $msg = $GUI_EVENT_CLOSE
  17.                         ExitLoop
  18.         EndSelect
  19. WEnd

  20. Exit

  21. Func Reciver($vParameter)

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

  25. EndFunc   ;==>Reciver


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

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

  35. EndFunc   ;==>Big


  36. Func Autoit3_Atuo_Step()

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

  41. 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() 后台模式,支持多文件下载,不用多进程~

  1. Func _CoProcSend($vProcess, $vParameter, $iTimeout = 500, $fAbortIfHung = True)
  2.         Local $iPid, $hWndTarget, $MyData, $aTmp, $COPYDATA, $iFuFlags
  3.         $iPid = ProcessExists($vProcess)
  4.         If Not $iPid Then Return SetError(1, 0, False) ; Process not Found
  5.         $hWndTarget = _ProcessGetWinList($vProcess, "", 16 + 2)
  6.         If @error Or (Not $hWndTarget) Then Return SetError(2, 0, False) ; Window not found
  7.         $MyData = DllStructCreate("char[" & StringLen($vParameter) + 1 & "]")
  8.         $COPYDATA = DllStructCreate("ptr;dword;ptr")
  9.         DllStructSetData($MyData, 1, $vParameter)
  10.         DllStructSetData($COPYDATA, 1, 1)
  11.         DllStructSetData($COPYDATA, 2, DllStructGetSize($MyData))
  12.         DllStructSetData($COPYDATA, 3, DllStructGetPtr($MyData))
  13.         If $fAbortIfHung Then
  14.                 $iFuFlags = 0x2 ; SMTO_ABORTIFHUNG
  15.         Else
  16.                 $iFuFlags = 0x0 ; SMTO_NORMAL
  17.         EndIf
  18.         $aTmp = DllCall("user32.dll", "int", "SendMessageTimeout", "hwnd", $hWndTarget, "int", 0x4A _; WM_COPYDATA
  19.                         , "int", 0, "ptr", DllStructGetPtr($COPYDATA), "int", $iFuFlags, "int", $iTimeout, "long*", 0)
  20.         If @error Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
  21.         If Not $aTmp[0] Then Return SetError(3, 0, False) ; SendMessageTimeout Failed
  22.         If $aTmp[7] <> 256 Then Return SetError(3, 0, False)
  23.         $aTmp = DllCall("user32.dll", "int", "PostMessage", "hwnd", $hWndTarget, "int", 0x400 + 0x64, "int", 0, "int", 0)
  24.         If @error Then Return SetError(4, 0, False)
  25.         If Not $aTmp[0] Then Return SetError(4, 0, False)
  26.         Return True
  27. EndFunc   ;==>_CoProcSend
复制代码

本帖子中包含更多资源

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

x
发表于 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 ...



  1. #include "CoProc.au3"

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

  9. $iPidBig = _CoProc("Big")
  10. GUISetState(@SW_SHOW)


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



  13. While 1
  14.         $msg = GUIGetMsg()
  15.         Select
  16.                 Case $msg = $GUI_EVENT_CLOSE
  17.                         ExitLoop
  18.         EndSelect
  19. WEnd

  20. Exit

  21. Func Reciver($vParameter)


  22.         GUICtrlSetData($Progress1,BinaryToString($vParameter) )

  23. EndFunc   ;==>Reciver


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

  27.         For $i = 1 To 10 Step 1
  28.                        
  29.                 _CoProcSend($gi_CoProcParent,StringToBinary($text[0]& $i & $text[1]) )
  30.                 Sleep(1000)
  31.         Next

  32. EndFunc   ;==>Big


  33. Func Autoit3_Atuo_Step()

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

  38. 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, 2019-10-24 11:28 , Processed in 0.078125 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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