Tomass Wilson Tomass Wilson - 4 months ago 14
Python Question

Python Multiprocessing outputting entire program

I don't normally ask questions on the internet nor am i a very good programmer, but i have been struggling with this problem for a while but i cant fathom why it doesn't work. I'm trying to do some maths that i thought i could do in multiple threads, the code below shows my attempt to output the answers that each worker comes to when it is done. I already realise that it is fairly inefficient, what with workers having to wait for others and surely many other problems, but i just want to get this version working. Any help is greatly appreciated

I am running windows 10, python 3.5, with 4 cores and 8 threads and running the program through the console,

Here is my code:

import math
from multiprocessing import Process, Lock
import time

lowMult = 0
highMult = 0
dist = "ERROR!"
print("Welcome to this maths test program")
print("We will be testing the nature of closest whole multiple pairs")
print("this test will run for all values 900000 to 900100")
print("press enter to begin")
input()

def worker(name, l, num):
l.acquire()
print (name, "Starting")
l.release()
found = False
test = math.sqrt(num)
if (test % 1) == 0:
l.acquire()
print(num, "=", int(test), "*", int(test), "0", "SQRT!")
l.release()

else:
test = int(test)
for lowMult in range(test, 0, -1):
for highMult in range(test, (num +1)):
if (lowMult * highMult) == num:
found = True
dist = highMult - lowMult
break

if found:
break

l.acquire()
if lowMult == 1:
print(num, "=", lowMult, "*", highMult, dist, "PRIME!")
else:
print(num, "=", lowMult, "*", highMult, dist)

print (name, "Exiting")
l.release()

if __name__ == '__main__':
lock = Lock()
jobs = []
num0 = 900000
num1 = 900001
num2 = 900002
num3 = 900003
for num in range(1, 100):
thread1 = Process(name='worker 1', target=worker, args=("worker 1", lock, num0,))
jobs.append(thread1)
thread1.start()

thread2 = Process(name='worker 2', target=worker, args=("worker 2", lock, num1,))
jobs.append(thread2)
thread2.start()

thread3 = Process(name='worker 3', target=worker, args=("worker 3", lock, num2,))
jobs.append(thread3)
thread3.start()

thread4 = Process(name='worker 4', target=worker, args=("worker 4", lock, num3,))
jobs.append(thread4)
thread4.start()

thread1.join()
thread2.join()
thread3.join()
thread4.join()

num0 += 4
num1 += 4
num2 += 4
num3 += 4

while True:
if thread1.is_alive() & thread2.is_alive() & thread3.is_alive() & thread4.is_alive():
time.sleep(2)
else:
input()
break


√Źn IDLE i get nothing, but i read around that this would happen, but in console i get the first few print commands instead of what i am expecting multiple times:

print("Welcome to this maths test program")
print("We will be testing the nature of closest whole multiple pairs")
print("this test will run for all values 900000 to 900100")
print("press enter to begin")


I get four of these before another input prompt, at which point the first calculation is done but it seems not to be in parallel, and the second is never finished. from my cpu usage it seems it never starts, but the program doesnt terminate. I have no idea what is going on.

EDIT:

It seems as though the actual computing problems lie within my use of
input()
and the definition of 'name'. a few other issues with
.join()
led me to remove them, and the
.is_alive()
check was fixed to use OR instead of AND. Nevertheless, when i run this code in python 3.5 and i get a windows console, I get four copies of this code unintentionally:

Welcome to this maths test program
We will be testing the nature of closest whole multiple pairs
this test will run for all values 900000 to 900100
press enter to begin


This is what i am currently trying to solve.

Answer

If you are using Python 2.7, then input() will likely "crash", because it is "equivalent to eval(raw_input(prompt))" according to the documentation: https://docs.python.org/2/library/functions.html#input

You could use raw_input for the purpose of reading user inputs (actually I don't see the point of asking for a keypress here).

Another problem is that the variable name is not defined in the worker function.

Also the thread1.is_alive() & thread2.is_alive() & thread3.is_alive() & thread4.is_alive() should always evaluate to False.

After removing all the input(), the output I get is (with Python 2.7) the following, which seems to be the expected result as I understand:

Welcome to this maths test program
We will be testing the nature of closest whole multiple pairs
this test will run for all values 900000 to 900100
press enter to begin
(900000, 'Starting')
(900001, 'Starting')
(900002, 'Starting')
(900003, 'Starting')
(900000, '=', 900, '*', 1000, 100)
('worker 1', 'Exiting')
(900003, '=', 611, '*', 1473, 862)
('worker 4', 'Exiting')
(900002, '=', 2, '*', 450001, 449999)
('worker 3', 'Exiting')
(900001, '=', 1, '*', 900001, 900000, 'PRIME!')
('worker 2', 'Exiting')
(900004, 'Starting')
(900005, 'Starting')
(900006, 'Starting')
(900007, 'Starting')
(900006, '=', 6, '*', 150001, 149995)
('worker 3', 'Exiting')
(900004, '=', 28, '*', 32143, 32115)
('worker 1', 'Exiting')
(900007, '=', 1, '*', 900007, 900006, 'PRIME!')
('worker 4', 'Exiting')
(900005, '=', 5, '*', 180001, 179996)
('worker 2', 'Exiting')
...
Comments