Home > Software design >  what difference between these two join methods in threading in python?
what difference between these two join methods in threading in python?

Time:11-18

I want to use threading package to calculate the square of num and my code like,

import threading
def my_squr(num):   #if this function take long time to run
    print(num*num)
    return num*num

if __name__ == "__main__":

    l1 = [1,3,5,7,11,13,15,17]
    for i, item in enumerate(l1):
        if i % 3 == 0:
            t1 = threading.Thread(target=my_squr, args=(item,))
            t1.start()
            t1.join()
        elif i % 3 == 1:
            t2 = threading.Thread(target=my_squr, args=(item,))
            t2.start()
            t2.join()
        else:
            t3 = threading.Thread(target=my_squr, args=(item,))
            t3.start()
            t3.join()

    # t1.join()
    # t2.join()
    # t3.join()

    print("Done")

However, I am confused about where should I put the join() method.Although, they both get same answer, I guess there are some differeces between them.

CodePudding user response:

If you immediately join after started an thread, it means that wait until it executes. However, this isn't different than calling function normally inside main thread. Assume that functions works takes a bit of time and you need to process them at the same time. Then you can start them and uncomment joins. This is your current code snippet workflow

->Create thread x and start
->wait for finish of thread x
->Create thread y and start
->wait for finish of thread y
... and so on.

However if you change comments of joins this is new workflow

->Create thread x and start
->Create thread y and start
->Create thread z and start
... 

at the end
->wait thread x to finish
->wait thread y to finish
...

So here even when you are waiting to finish X, your other threads like y and z still processing whatever you are doing inside.

EDIT: You should remove the joins where right after the start and uncomment threads that are been in the end. That would be a more appropriate. Also, as processors are fast enough to complete simple math just in a millisecond, you will not experience any difference.

Where u should use the joins is completely dependent on your program. For your situation using at the end probably would be the best.

However, assume you will have another thread called X_2 that will use result of thread X_1. Then before creating thread X_2, you should join thread X_1.

CodePudding user response:

You could construct a list of the threads then join them all once your loop terminates:

import threading
def my_squr(num):   #if this function take long time to run
    print(num*num)
    return num*num

if __name__ == "__main__":
    threads = []
    l1 = [1,3,5,7,11,13,15,17]
    for i, item in enumerate(l1):
        if i % 3 == 0:
            t1 = threading.Thread(target=my_squr, args=(item,))
            t1.start()
            threads.append(t1)
        elif i % 3 == 1:
            t2 = threading.Thread(target=my_squr, args=(item,))
            t2.start()
            threads.append(t2)
        else:
            t3 = threading.Thread(target=my_squr, args=(item,))
            t3.start()
            threads.append(t3)

    for thread in threads:
        thread.join()

    print("Done")

CodePudding user response:

Join simply stops the application from ending before the thread completes.
So you want to join threads AFTER they have started.

import threading
def my_squr(num):   #if this function take long time to run
    print(num*num)
    return num*num

if __name__ == "__main__":
    threads = list()
    l1 = [1,3,5,7,11,13,15,17]
    for i, item in enumerate(l1):
        if i % 3 == 0:
            t1 = threading.Thread(target=my_squr, args=(item,))
            threads.append(t1)
            t1.start()
        elif i % 3 == 1:
            t2 = threading.Thread(target=my_squr, args=(item,))
            threads.append(t2)
            t2.start()
        else:
            t3 = threading.Thread(target=my_squr, args=(item,))
            threads.append(t3)
            t3.start()

    for t in threads:
        t,join()

    print("Done")
  • Related