0

I need to run a function in another thread, and get the return value of that function to save it to a variable in the main thread. Basically, my code calls the function, which communicates with a balance through a serial port, waits for and gets the response, parses the response, and returns the response as a float. I need to capture this float so I can save it. This is my code:

from multiprocessing.pool import ThreadPool

pool = ThreadPool(processes=2)
result = pool.apply_async(manual_short_command, (self.status_signal2, self.conn, command, status_string, 2))
self.readout = result.get()

def manual_short_command(signal, conn, command, status_string, string_arg='', timeout=60):
""" Send specified command (expects a balance response)to balance through "conn" and emit status signal """
print "Command: " + command.strip('\r\n')
emit_status(signal, status_string[0], string_arg)
if not conn.isOpen():
    conn.open()
# Wait until nothing can be read at the balance port
while not timeout and conn.readlines():
    time.sleep(1)
    timeout -= 1
# Write the command to the balance port and wait for response
while timeout:
    time.sleep(1)
    conn.write(command)
    resp = conn.readlines()

    try:
        resp = float(resp[0])
    except ValueError:
        pattern = r'(.?\d+\.\d+)'
        match = re.findall(pattern, resp[0])
        resp = float(match[0])
    except IndexError:
        continue

    print resp
    print 'timeout: %s' % timeout
    if resp:
        emit_status(signal, status_string[1], str(resp))
        print resp, 'here'
        return resp

    timeout -= 1
conn.close()
print resp
return resp

I start the function manual_short_command in another thread, and this function sends a command through a serial port and waits for a response. It then returns this response and writes it on the status browser (I'm using PyQt4 for the GUI but I think that is irrelevant).

I get an error when I try to assign self.readout = result.get(), saying IndexError: list index out of range, which means that the function hasn't completed in the other thread yet. How do I wait for the thread to finish before I assign the result? My program hangs otherwise. I looked at Threading pool similar to the multiprocessing Pool? for some guidance, but I couldn't find how to synchronize the two threads. Any suggestions? Sorry for the huge block of code.

Community
  • 1
  • 1
Peter Wang
  • 1,808
  • 1
  • 11
  • 28
  • Why are you using multithreading if you want to only run one thread at a time? See if you can do it without multithreading. – Eli Sadoff Jun 30 '16 at 19:25
  • In my first thread the GUI needs to have a countdown timer to let the machine stabilize, so it needs to be counting down as the second thread is running. If they are running in the same thread, the countdown timer won't work – Peter Wang Jun 30 '16 at 20:49
  • 1
    Sorry! I am so used to people trying to multithread for no reason. I'm an idiot. – Eli Sadoff Jun 30 '16 at 20:58

1 Answers1

2

You can use join(). This will make the program to wait until the thread finish, and then will move next to show the result.

Ami Hollander
  • 2,435
  • 3
  • 29
  • 47
  • I get `AttributeError: 'ApplyResult' object has no attribute 'join'`. This isn't a Thread object, it's using a ThreadPool and it returns an ApplyResult with attributes get(), wait(), ready(), successful(). https://docs.python.org/2/library/multiprocessing.html#multiprocessing.pool.multiprocessing.Pool.apply_async I tried adding a while loop to wait for it to finish: `while not result.ready(): time.sleep(1)`, but that doesn't seem to work either. There is still no return result to call get() on. – Peter Wang Jun 30 '16 at 21:03
  • You can find a solution here: http://stackoverflow.com/questions/20577472/how-to-keep-track-of-asynchronous-results-returned-from-a-multiprocessing-pool – Ami Hollander Jul 01 '16 at 09:20
  • I cant see your changes in the code, so it is hard for me to help you. But, I think `join` can help you, and you can see an example in the link above, good luck. – Ami Hollander Jul 01 '16 at 09:21
  • @PeterWang If you found this solution relevant, you can mark it as solved – Ami Hollander Jul 04 '16 at 12:29