2

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.

3
  • If you start a thread an immediately join it you can skip the thread and just perform the operation in a normal function call, no multithreading needed, will have basically the exact same effect. Commented Nov 18, 2022 at 8:30
  • Does this answer your question? What is the use of join() in Python threading? Commented Nov 18, 2022 at 8:31
  • @luk2302 thanks for your reply, I am still confused about this method after reading website, did it means it is meaningless of join method, join is only to make the code clear? Commented Nov 18, 2022 at 8:55

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks again, did you mean it is not necessary to add join in anywhere? sorry, I am still confused, if my_squr takes long time to run, which one is correct?
In your situation, using at the end would be correct
@4daJKong, Re, "...not necessary to add join anywhere?" t.join() is how one thread can wait for another thread to end. If thread t does some thing, and *IF* there's some point in some other thread u beyond which u should not proceed until t has done its thing, then thread u can call t.join() at that point, and the join call will not return until thread t has done its thing.
@4daJKong, In your example, the last thing your main thread does is, print("done"). If you don't want that to happen until after the other three threads are done, then you can ensure that by having the main thread join() all of those other threads before it prints the "done" message.
1

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")

2 Comments

thanks for your reply, the main problem is I don't know where should I add join, in loop or out loop, because they both return same reuslt, but I want to use mulitthreading
The join in my answer is outside the loop - i.e., it's a clean-up operation. I'm interested to know what your long-running function will be doing. I hope it's not going to be CPU intensive because, if it is, multithreading will not be a good option
1

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")

3 Comments

thanks for your reply, the main problem is I don't know where should I add join, in loop or out loop, because they both return same reuslt, but I want to use mulitthreading
Re, "join...stops the application." That's a misleading assertion. t.join() waits for thread t to end. If you happen to call t.join() from some thread that you think of as "the application," then sure, join stops the application. But any thread can join any other thread. The simplest explanation for what join does is the one that explains how it behaves in any situation. t.join() does nothing. It continues to do nothing until thread t ends, and then it returns.
Without join your application would end before the threads completed.... thus join STOPS your application from continuing. If you haven't launched another thread BEFORE you join then the other thread can't start. My solution is correct because I join AFTER all the threads are started.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.