Jump to content

multi threading


 Share

Recommended Posts

  • Replies 60
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

5 minutes ago, Petrask24 said:

Is it possible to have a return value (or message) from a function within the thread?

anything is possible it just depends on how creative you are.  The messages between threads (in my mind) are more of a timing/trigger mechanism.  If you plan to use many variables that go beyond ultra simplistic your best bet is using a shared .ini file.  You can store virtually an unlimited amount of variables in there.  They are also nice for saving settings or other information that you'd wish to have longer term.  The only thing you have to be careful about there is haven't multiple threads attempting to write to it at the same time. 

Link to comment
Share on other sites

3 minutes ago, argumentum said:

..hence, bad idea :P 

i mean you can use a mutex...

i'm just thinking if only one thread is changing certain data and another is just reading it.  its possible to read incorrect data if its not refreshed but the msg can be that new data was written to reopen the file.  Idk, i have no idea what this guy is doing.

Edited by markyrocks
Link to comment
Share on other sites

3 minutes ago, Petrask24 said:

It really seemed like this was going to be a simple concept.. 😆

Here is the idea I'm going for... Whichever thread ends up true = the amount of slots available.

#include <authread.au3>

_AuThread_Startup()

Func _GetAvailableSlots()

    Global $slots = -1

    $thread1 = _AuThread_StartThread("thread1")
    $thread2 = _AuThread_StartThread("thread2")
    $thread3 = _AuThread_StartThread("thread3")
    $thread4 = _AuThread_StartThread("thread4")

    ConsoleWrite($slots & @CRLF)

EndFunc

Func thread1()
    If (True) Then
        $slots = 1
    EndIf
EndFunc

Func thread2()
    If (False) Then
        $slots = 2
    EndIf
EndFunc

Func thread3()
    If (False) Then
        $slots = 3
    EndIf
EndFunc

Func thread4()
    If (False) Then
        $slots = 4
    EndIf
EndFunc

_GetAvailableSlots()

 

Link to comment
Share on other sites

@markyrocks, if one can avoid using a disk, better for the whole PC and running apps.
If is to "write" in order without timing issues, MailStots is a good solution. Pipes, ...there are many ways but writing to disk should be a last option.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

looks like the outcome is predetermined.  Fyi threads only work in while loops.  as you have it now they all execute so fast you have no idea if they are happening at the same time.  the purpose of threads is to have things that take large amounts of time (or indeffinetly) happen side by side.  Like a video game can't dedicate the whole process to wait for a user to press a key, thats just one thread that monitors user input etc.

Link to comment
Share on other sites

2 minutes ago, markyrocks said:

looks like the outcome is predetermined.  Fyi threads only work in while loops.  as you have it now they all execute so fast you have no idea if they are happening at the same time.  the purpose of threads is to have things that take large amounts of time (or indeffinetly) happen side by side.  Like a video game can't dedicate the whole process to wait for a user to press a key, thats just one thread that monitors user input etc.

I'll be doing an image search in each of them, which as I have it set up could take a bit of time.

#include <authread.au3>

_AuThread_Startup()

Func _GetAvailableSlots()

    Global $slots = -1

    $thread1 = _AuThread_StartThread("thread1")
    $thread2 = _AuThread_StartThread("thread2")
    $thread3 = _AuThread_StartThread("thread3")
    $thread4 = _AuThread_StartThread("thread4")

    ConsoleWrite($slots & @CRLF)

EndFunc

Func thread1()
    Local $x1 = 0, $y1 = 0
    $result = _ImageSearchArea($Image, 1, $WindowX, $WindowY, $WindowX, $WindowY, $x1, $y1, 0, 0)
    If ($result) Then
        $slots = 1
    EndIf
EndFunc

Func thread2()
    Local $x1 = 0, $y1 = 0
    $result = _ImageSearchArea($Image, 1, $WindowX, $WindowY, $WindowX, $WindowY, $x1, $y1, 0, 0)
    If ($result) Then
        $slots = 2
    EndIf
EndFunc

Func thread3()
    Local $x1 = 0, $y1 = 0
    $result = _ImageSearchArea($Image, 1, $WindowX, $WindowY, $WindowX, $WindowY, $x1, $y1, 0, 0)
    If ($result) Then
        $slots = 3
    EndIf
EndFunc

Func thread4()
    Local $x1 = 0, $y1 = 0
    $result = _ImageSearchArea($Image, 1, $WindowX, $WindowY, $WindowX, $WindowY, $x1, $y1, 0, 0)
    If ($result) Then
        $slots = 4
    EndIf
EndFunc

_GetAvailableSlots()

 

Link to comment
Share on other sites

3 minutes ago, argumentum said:

@markyrocks, if one can avoid using a disk, better for the whole PC and running apps.
If is to "write" in order without timing issues, MailStots is a good solution. Pipes, ...there are many ways but writing to disk should be a last option.

I'm just going for simplicity.  an ini is probably the simplest solution for a relatively new user.   Then again i probably wouldn't recommend going down this path at all unless the person had at least a decent mastery of autoit in general.   Everyone has ssd's anymore reading and writing from disc isn't much of an issue especially if you're only talking kbs at a time.   I mean literally  the way the whole messages system is setup using temporary text files in the authread.au3  least last time i checked thats how it worked.  

Link to comment
Share on other sites

11 minutes ago, Petrask24 said:

I'll be doing an image search in each of them, which as I have it set up could take a bit of time.

if all you're doing is trying to determine if there was a hit or not in a thread the built in message system should work just fine.  Have it return either false or the position.  Idk if you can message an array you will probably have to convert it to a string or something and then convert back.

Link to comment
Share on other sites

1 minute ago, markyrocks said:

if all you're doing is trying to determine if there was a hit or not in a thread the built in message system should work just fine.  Have it return either false or the position.  Idk if you can message an array you will probably have to convert it to a string or something and then convert back.

Honestly, all I need it to return is true or false.

Link to comment
Share on other sites

  • Developers

@Petrask24,

I have merged your crossposted topic here so we have one place to discuss your question... so please stick to one place for the future.
Also be patient.....  people will reply when they have time and feel like helping, but do not try bumping your issue within 24 hours.

In the mean time, why not explain what exactly is the purpose of this script? Why is this multiple image search at the same time required?

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

On 9/7/2020 at 3:42 AM, Jos said:

@Petrask24,

I have merged your crossposted topic here so we have one place to discuss your question... so please stick to one place for the future.
Also be patient.....  people will reply when they have time and feel like helping, but do not try bumping your issue within 24 hours.

In the mean time, why not explain what exactly is the purpose of this script? Why is this multiple image search at the same time required?

Jos

Thanks for merging that for me, @Jos. I'll try to further explain my script and the issue I'm having.

Please note that I've modified this script from past posts.

The variable $slots will be used in future code. The idea is to have the image searches happen continuously until they either return true or timeout.

I found this in some documentation online that could be helpful: int _AuThread_StartThread(string $sCallback [, string $sMsg ] )

Could I somehow use this callback to get the first variable to return (and possibly end all other processes)?

#include <authread.au3>
#include <ImageSearch2015.au3>

Global $slots = -1

_AuThread_Startup()
_GetAvailableSlots()

Func _GetAvailableSlots()

    $thread1 = _AuThread_StartThread("thread1")
    $thread2 = _AuThread_StartThread("thread2")
    $thread3 = _AuThread_StartThread("thread3")
    $thread4 = _AuThread_StartThread("thread4")

EndFunc

Func thread1()
    Local $x1 = 0, $y1 = 0, $WindowX = 0, $WindowY = 0, $WindowXX = 1200, $WindowYY = 900, $Timeout = 5000
    Local $Image1 = "Images/Image1.PNG", $Image2 = "Images/Image2.PNG"
    Local $Image3 = "Images/Image3.PNG", $Image3 = "Images/Image4.PNG"
    $Timer = TimerInit()
    do
        $result = _ImageSearchArea($Image1, 1, $WindowX, $WindowY, $WindowXX, $WindowYY, $x1, $y1, 0, 0)
    until $result or TimerDiff($Timer) >= $Timeout
    If ($result) Then
        $slots = 1  ;This does not work since it is a "separate process"
                    ;Add code here to return the value of 1 for $slots
    EndIf
EndFunc

Func thread2()
    Local $x1 = 0, $y1 = 0, $WindowX = 0, $WindowY = 0, $WindowXX = 1200, $WindowYY = 900, $Timeout = 5000
    Local $Image1 = "Images/Image1.PNG", $Image2 = "Images/Image2.PNG"
    Local $Image3 = "Images/Image3.PNG", $Image3 = "Images/Image4.PNG"
    $Timer = TimerInit()
    do
        $result = _ImageSearchArea($Image1, 1, $WindowX, $WindowY, $WindowXX, $WindowYY, $x1, $y1, 0, 0)
    until $result or TimerDiff($Timer) >= $Timeout
    If ($result) Then
        $slots = 2  ;This does not work since it is a "separate process"
                    ;Add code here to return the value of 2 for $slots
    EndIf
EndFunc

Func thread3()
    Local $x1 = 0, $y1 = 0, $WindowX = 0, $WindowY = 0, $WindowXX = 1200, $WindowYY = 900, $Timeout = 5000
    Local $Image1 = "Images/Image1.PNG", $Image2 = "Images/Image2.PNG"
    Local $Image3 = "Images/Image3.PNG", $Image3 = "Images/Image4.PNG"
    $Timer = TimerInit()
    do
        $result = _ImageSearchArea($Image1, 1, $WindowX, $WindowY, $WindowXX, $WindowYY, $x1, $y1, 0, 0)
    until $result or TimerDiff($Timer) >= $Timeout
    If ($result) Then
        $slots = 3  ;This does not work since it is a "separate process"
                    ;Add code here to return the value of 3 for $slots
    EndIf
EndFunc

Func thread4()
    Local $x1 = 0, $y1 = 0, $WindowX = 0, $WindowY = 0, $WindowXX = 1200, $WindowYY = 900, $Timeout = 5000
    Local $Image1 = "Images/Image1.PNG", $Image2 = "Images/Image2.PNG"
    Local $Image3 = "Images/Image3.PNG", $Image3 = "Images/Image4.PNG"
    $Timer = TimerInit()
    do
        $result = _ImageSearchArea($Image1, 1, $WindowX, $WindowY, $WindowXX, $WindowYY, $x1, $y1, 0, 0)
    until $result or TimerDiff($Timer) >= $Timeout
    If ($result) Then
        $slots = 4  ;This does not work since it is a "separate process"
                    ;Add code here to return the value of 4 for $slots
    EndIf
EndFunc

Thanks in advance, I appreciate you taking the time.

Edited by Petrask24
Updated Code, Tagged Jos, Fixed Code
Link to comment
Share on other sites

untested but should look something like this.  You need to have a main thread otherwise the main script will just execute in a matter of seconds and exit

Global $slots = -1

_AuThread_Startup()
_GetAvailableSlots()  ;<~~~~~~~~~was no () here

;main thread

while 1
    $slots=_auThread_GetMessage()

    sleep(5)
;if slots do something
;else wait so long and bug out

if slots Then
    if ProcessExists($thread1) then ProcessClose($thread1)
    if ProcessExists($thread2) then ProcessClose($thread2)
    if ProcessExists($thread3) then ProcessClose($thread3)
    if ProcessExists($thread4) then ProcessClose($thread4)
        
endif

    WEnd

Func thread1()
    local $result
    Local $x1 = 0, $y1 = 0, $WindowX = 0, $WindowY = 0, $WindowXX = 1200, $WindowYY = 900, $Timeout = 5000
    Local $Image1 = "Images/Image1.PNG", $Image2 = "Images/Image2.PNG"
    Local $Image1 = "Images/Image3.PNG", $Image3 = "Images/Image4.PNG"
    $Timer = TimerInit()
    do
        ;$result = _ImageSearchArea($Image1, 1, $WindowX, $WindowY, $WindowXX, $WindowYY, $x1, $y1, 0, 0)
    until $result or TimerDiff($Timer) >= $Timeout
    If ($result) Then
        $slots = 1
     _AuThread_SendMessage(_AuThread_MainThread(),$slots)
    EndIf
EndFunc

I'd also like to add that you should probably have the main thread do some of the work otherwise its just sitting there waiting.  Kinda pointless.

edit it also looks like you define $Image1 and then redefine it again, i'm assuming that's a mistake.

Edited by markyrocks
Link to comment
Share on other sites

For anyone that may be interested, this is the solution I ended up settling with.

#include <authread.au3>
#include <ImageSearch2015.au3>

Global $Image1 = "Image1.PNG"
Global $Image2 = "Image2.PNG"
Global $x1 = 0
Global $y1 = 0
Global $WindowX = 500
Global $WindowY = 500
Global $WindowXX = 1000
Global $WindowYY = 1000
Global $Timeout = 5000
Global $Window_Name = "untitled - Notepad"
Global $Message = ""

test3()

Func Test3()

    _AuThread_Startup()
    WinActivate($Window_Name)

    $thread1 = _AuThread_StartThread("thread1")
    $thread2 = _AuThread_StartThread("thread2")

    $Timer = TimerInit()
    do
        $Message = _AuThread_GetMessage()
    until $Message or TimerDiff($Timer) >= 5000
    ConsoleWrite($Message & @CRLF)
EndFunc

Func thread1()
    $Window = WinGetPos($Window_Name)
    $Timer = TimerInit()
    do
        $result = _ImageSearchArea($Image1, 1, $Window[0] + $WindowX, $Window[1] + $WindowY, $Window[0] + $WindowXX, $Window[1] + $WindowYY, $x1, $y1, 0, 0)
    until $result = 1 or TimerDiff($Timer) >= $Timeout
    If ($result) Then
        _AuThread_SendMessage(_AuThread_MainThread(), 1)
    EndIf
EndFunc

Func thread2()
    $Window = WinGetPos($Window_Name)
    $Timer = TimerInit()
    do
        $result = _ImageSearchArea($Image2, 1, $Window[0] + $WindowX, $Window[1] + $WindowY, $Window[0] + $WindowXX, $Window[1] + $WindowYY, $x1, $y1, 0, 0)
    until $result = 1 or TimerDiff($Timer) >= $Timeout
    If ($result) Then
        _AuThread_SendMessage(_AuThread_MainThread(), 2)
    EndIf
EndFunc

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...