Python Multiprocessing outputting entire program
Question: 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')
    ...
    

