How to multi thread

Asked by Danielo

Hello everyone. I have a little problem and i don't know how to solve it.

I have two scripts, call it, A and B.

A uses functions from B

B have a function like this

things=[thing,thing,thing...]
def search( ):
   for t in things:
      if exists(t)
       click(t)
       do a lot of things

Ok, i want to execute that function from a but in background. So, i want to call tath function without stopping A script doing things.

A:

while true:
   clic(x)
   wait(1)
   b.search()
   more things.

I don't know if i explained this well.

I though about call the b function with a different value in each iteration, to make it less slow, but i don't know how to access to the differents parts of an array in sikuli.

Thank you every onee, and sorry for my bad english.

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:
Revision history for this message
Best RaiMan (raimund-hocke) said :
#1

You already decided to wait for a bug free observe feature ;-)

observe might be the best solution in many cases, where you want to wait for different visual events may be in different regions and then do some actions. it is really some kind of a dispatcher feature.

But you always have to be aware, that too many observations in parallel might produce a chaos, since we only have one mouse and one keyboard. And you have to take care, that one action does not mislead another observation (e.g. opening some windows, that overlap observed regions).

so: it is a powerful feature and will even be more powerful with rc2 (the docs are already talking about ;-), but ....

--- If you really want to "multi tread": all the standard Python features like thread and threading work fine in Sikuli and have many more options to synchronize the usage of mouse, keyboard and other assets.

simple example:

def stopSelect(t): # this will be threaded
 wait(t)
 mouseDown(Button.RIGHT)
 mouseUp()

def myAlarm(text, t=2):
 import thread
 thread.start_new_thread(stopSelect, (t, ))
 selectRegion(text)

using
myAlarm("the text to be displayed")
would display the capture overlay with the message for 2 seconds and then automatically vanish, because of the right mouse click in the thread setup with stopSelect().

--- I have experimented with another thing:
running a thread, that constantly tracks mouse location and is able to recognize simple gestures (e.g. going to the screen borders and corners) to e.g. support measuring visual objects and in a popup shows a "Region(x,y,w,h)" that can be used in a script.

--- Another option for limited "parallel processing" is to use the XMLRPC feature.
If interested: https://answers.launchpad.net/sikuli/+faq/1331

Revision history for this message
Danielo (rdanielo-gmail) said :
#2

Your answer is exactly what i was looking for, thank you, really awesome man. But i can't make it to work properly.

Here is my example, and i don't know what I'm doing wrong

def buscador( ):
 popup("Buscador inicializado")
 reg.highlight();
 while True:
  for b in bichos:
   b=reg.exists(bug)
   print "I'm Alive"
   popup("Buscando")
   if b:
    reg.getLastMatch().highlight()

thread.start_new_thread(buscador, ( ) )
while True:
 click( )# )
 sleep(0.2)
 segar=exists( )
 if segar:
  click(getLastMatch())

 if exists(level_up):
  click(level_up)
 sleep(7)

In buscador the first popup works, even the highlight, but nothing happens inside the while loop.
I tried to remove the while, and it still doing nothing.

Really appreciatte your help man, you're my new hero.

Revision history for this message
Danielo (rdanielo-gmail) said :
#3

Thanks RaiMan, that solved my question.

Revision history for this message
Danielo (rdanielo-gmail) said :
#4

Please, forget that comment, the error were on the reg.exists, it should be b instead of bug, but i can't understand why this stops the thread.

Now, the program works perfectly, but i don't know how to stop the thread when
I force to kit the script with alt+shift+c

How can i do that without the task killer?

Revision history for this message
RaiMan (raimund-hocke) said :
#5

since reg is not defined in the local context and supposing it is not a global variable, this should raise a Name exception and stop the thread. We ;-) should have a look, how to catch this and where (Python docs).

A thread is ended, when it gets to an explicit or implicit return. If It is ended if the main dies, depends on the system around. On my Mac, it seems, that the sub is ended, when the main ends (but not really sure).

So if you use the your forced termination, you have to live with it.

You might try to use some "I'm alive" status with the locking feature.
Here is something to play with:

import thread
def sub(alive):
 while True:
  x = alive.locked()
  print "sub running:", x
  if not x:
   print "sub stopped:", x; return
  wait(3)

print "main started"
alive = thread.allocate_lock()
if alive.acquire(): print "main locked:", alive.locked()
else: exit(1)
thread.start_new_thread(sub, (alive, ))
wait(10)
alive.release() # sub stops after this

maybe the lock is set to false (that's what we need), when main vanishes. give it a try.