I have a function that factor a number. It depends on some random condition.
So what I am trying to do it’s to run multiple processors in this function and the processor that finds the factor first returns the value and all processors terminate.
What I have so far is very wrong. The processors are not terminating and I also don’t know how to get the value that was returned by the function
flag = False def rho(n, processor): while True: x = random.randrange(1, n-1) x2 = x gcd = 1 c = random.randrange(1, n-1) while gcd == 1: x = (x**2 + c) % n x2 = (x2**2 + c) % n x2 = (x2**2 + c) % n gcd = math.gcd(abs(x - x2), n) if gcd != n: flag = True print("Factor was found from "+process+" and is ", gcd) return gcd if __name__ == "__main__": p1 = multiprocessing.Process(target=rho, args=(91, "process 1" )) p2 = multiprocessing.Process(target=rho, args=(91, "process 2")) p1.start() p2.start() if flag: p1.terminate() p2.terminate()
The output is:
Factor was found from process 2 and is 13 Factor was found from process 1 and is 7
Advertisement
Answer
You can use multiprocessing.Pool
and it’s methods map()
, imap_unordered()
etc. These will return also values from worker functions.
Example (I used time.sleep()
to simulate some time-intesive computation):
from time import sleep from multiprocessing import Pool def rho(params): n, processor = params # your computation here # ... sleep(n) print("Factor was found from " + processor + " and is 42") return 42 if __name__ == "__main__": with Pool() as pool: for result in pool.imap_unordered( rho, ((10, "process 1"), (1, "process 2")) ): print("Result I got:", result) break # <-- I don't want other results, so break
Prints:
Factor was found from process 2 and is 42 Result I got: 42
EDIT: Two different functions:
from time import sleep from multiprocessing import Pool def fn1(n, p): sleep(n) print("Factor was found from " + p + " and is 42") return 42 def fn2(n, p): sleep(n) print("Factor was found from " + p + " and is 99") return 99 def rho(params): what_to_call, n, processor = params return what_to_call(n, processor) if __name__ == "__main__": with Pool() as pool: for result in pool.imap_unordered( rho, ((fn1, 10, "process 1"), (fn2, 1, "process 2")) ): print("Result I got:", result) break # <-- I don't want other results, so break