简体   繁体   中英

what does exactly the join() method do in python multithreading

I'm still learning how to use multithreading, and I'm confused about how the join() method works. based on what I read, the join() method stops everything until the thread terminates. but take a look at this code:

from threading import Thread

def do_something(i):
    print("Sleeping...")
    time.sleep(i)
    print(f"Done sleeping {i}")

start = time.perf_counter()

t1, t2 = Thread(target=do_something, args=(1,)), Thread(target=do_something, args=(10,))

t1.start()
t2.start()

t2.join()
print("t2 joined")
t1.join()
print("t1 joined")

And when we run this, it gave us the output below:

Sleeping...
Sleeping...
Done sleeping 1
Done sleeping 10
t2 joined
t1 joined

As you can see, I used t2.join() right after starting both threads, but the first thing that got printed is Done sleeping 1 . But based on what I thought join() will do, I expected t1 to be stopped, and the program gave us the output below:

Sleeping...
Sleeping...
Done sleeping 10
Done sleeping 1
t2 joined
t1 joined

Can someone explain to me what I got wrong?

It waits for the thread to finish. That's all it does. Nothing more, and nothing less.

Like running multiple independent programs simultaneously, running multiple threads simultaneously also has similar features with some added benefits, which are as follows:

Multiple threads share the same data space along with the main thread within a process. Hence, they can easily share information or can communicate with each other unlike if they were processes.

Also known as light weight processes, they require less memory overhead and hence are cheaper than processes.

Multi threading is defined as the ability to execute multiple threads simultaneously or concurrently. Hence more than one thread can exists in a single process where:

Methods for Joining Threads

On invoking the join() method, the calling thread gets blocked until the thread object (on which the thread is called) gets terminated. The thread objects can terminate under any one of the following conditions

Through an ill-handled exception. Till the optional timeout occurs or normaly

Example:

from threading import Thread
from threading import Event
import time


class Connection(Thread):

    StopEvent = 0
    
    def __init__(self,args):
        Thread.__init__(self)
        self.StopEvent = args

    # The run method is overridden to define
    # the thread body
    def run(self):

        for i in range(1,10):
            if(self.StopEvent.wait(0)):
                print ("Asked to stop")
                break;

            print("The Child Thread sleep count is %d"%(i))
            time.sleep(3)
        
        print ("A Child Thread is exiting")

Stop = Event()
Connection = Connection(Stop)       
Connection.start()
print("Main thread is starting to wait for 5 seconds")

Connection.join(5)
print("Main thread says : I cant't wait for more than 5 \
seconds for the child thread;\n Will ask child thread to stop")

# ask(signal) the child thread to stop
Stop.set()

# wait for the child thread to stop
Connection.join()

print("Main thread says : Now I do something else to compensate\
the child thread task and exit")
print("Main thread is exiting")

When you join thread, it means every thread waits for the other to finish before terminating.

if you write

t2.join()
t1.join()

it means t2 and t1 are gonna wait for each other to finish before terminating (essentially "killing" the thread)

Essentially, it has to do with what we call deamon thread Initially, in python, once a thread finished it's job, it would terminate the whole program if it had nothing to do after.

The way to avoid that was to call.join() on every thread, which mean they would wait for every thread to finish before continuing (and potentially finishing the program)

Nowaday, thread are not deamon by default anymore (you can still make them deamon with a keyword argument).

So by default, once a thread has finished it's task it's gonna wait for every thread to finish before stopping.

t.join() method will block the calling thread until thread t finished. I don't know how join() implemented, but probably it use semaphore mechanism. Please look at this also. Below myJoin() method will do same job mostly like join() method of Thread class did. Below program is only simple example to understand the background

from threading import Thread,Event
from time import sleep

class MyThread(Thread):

    def __init__(self):
        Thread.__init__(self)
        self.event=Event()

    def run(self):
        try:
            for i in range(5):
                print(i)
                sleep(1)
        finally:
            self.event.set()

    def myJoin(self,timeout=None):
        self.event.wait(timeout=timeout)

t = MyThread()
t.start()

print("waiting for thread t to finish")

t.myJoin()

print("thread t finished")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM