fsociety
fsociety

Reputation: 1027

Python Multithreading basics confusion

I have the below code:

import time
from threading import Thread

def fun1():
 time.sleep(5)

def fun2():
 time.sleep(5)

def fun3():
 time.sleep(5)

def fun4():
 time.sleep(5)

if __name__ == '__main__':
  t1 = Thread(target=fun1, args=())
  t2 = Thread(target=fun2, args=())
  t3 = Thread(target=fun3, args=())
  t4 = Thread(target=fun4, args=())
  t1.start()
  t2.start() 
  t3.start() 
  t4.start()
  start = time.clock()
  t1.join()
  t2.join()
  t3.join()
  t4.join()
  end = time.clock()
  print("Time Taken = ",end-start)

Que1: At a time only one thread will be serviced, meaning if the control is with thread t1,rest other threads will be waiting. Once the context switch takes place to thread t2,rest all other threads(t1,t3 and t4) will be waiting. Is that the correct understanding?

Que2:If my understanding of Que1 is true, the total time(start - end) should be twenty seconds(as good as running in sequential manner rather than threaded manner)...but it is somewhat close to 5 seconds....why?At the end of the day,the threads are getting executed in sequence(though, not in entirety) one by one Please explain in laymen terms.Where is my understanding incorrect?

Que3:What if i do the same thing using multiprocessing?How will the execution differ?

Que4:Let's say(assume) fun1() has the code that does a 1000 repeat count ping to Router 1 and takes a time of 1 min. Similary, fun2() does a 1000 repeat count ping to Router 2 and takes a time of 1 min. Similary, fun3() does a 1000 repeat count ping to Router 3 and takes a time of 1 min.

If i do this sequentially, total expected time is 3 min for(ping to R1,then ping to R2 and then ping to R3) But when i did this using threading,the total execution time was almost close to 1 min. Why ? I am unable to understand.

Upvotes: 2

Views: 258

Answers (3)

Craig Burgler
Craig Burgler

Reputation: 1779

Q1: Yes

Q2: If the threads each did something that took 5 seconds of processing time, then you would expect the total time to be 20 seconds. But each thread is just sleeping for 5 seconds, so each thread releases the GIL, and thus allows other threads to run "in parallel" (only conceptually), as it waits for the sleep timeout.

Q3: Multiprocessing, unlike threads, creates child processes which can each run on different processors concurrently (actually parallel). But even if these sleeps each run on separate processors, they will still collectively finish in about 5 seconds. If they run on the same processor the OS's time-sharing mechanism will, in a manner similar to Python's threading mechanism, also ensure they complete in about 5 minutes.

Q4: It's the same concept as with sleep. Each ping is not CPU-intensive and thus its thread rarely has possession of the GIL. This allows all three ping threads to conceptually run in parallel.

Upvotes: 2

hainguyen
hainguyen

Reputation: 111

For multithreading environment in python. We have two very different kind of taks:

  • CPU bound: like adding number, running for loop ... any activities that consume CPU. This kind of task hold GIL so it prevent other thread running.
  • not CPU bound (may be waiting for IO activities from outside resource like network ...):sleep system call does not use CPU so it's in this kind. this kind releases GIL while it waits for IO, sleep timeout .. so other thread can take lock and running. That is why your program take around 5 seconds because all of your threads can run in parallel.

Upvotes: 1

ShadowRanger
ShadowRanger

Reputation: 155403

Blocking calls in Python (sleep, waiting on I/O or locks) release the GIL, allowing other threads to run while they are blocked, so all four threads can sleep in parallel, that's why you're seeing a five second delay. If you want to see the effects of GIL contention, have the thread function do something CPU bound, e.g.

def fun():
    for _ in xrange(1000000000):
        pass

multiprocessing won't change a thing for the sleep case, since you're not GIL bound, but it would improve the wall clock time of the CPU bound case if you have more than one core to run on.

Upvotes: 3

Related Questions