Start and stop a thread in Python



Code # 1:

# Code to run in an independent thread

import time

 

def countdown (n):

while n & gt;  0 :

print ( `T-minus` , n)

n - = 1

time.sleep ( 5 )

 
# Create and run stream

from threading import Thread

t = Thread (target = countdown, args = ( 10 ,))

t.start () 

When a thread is instantiated, it does not start executing until its start () method is called (which calls the target function with the arguments you specify). Threads run in their own system-level thread (for example, POSIX thread or Windows threads), which is completely controlled by the host operating system. Once started, the threads run independently until the target function returns.

Code # 2: Request a thread instance to see if it is still running.

if t.is_alive ():

  print ( `Still running` )

else :

print ( `Completed` )

You can also request to join a stream that is waiting for it to complete.

t.join ()

The interpreter continues to run until all threads have finished. For long running threads or background tasks that run forever, consider making the thread daemonic.

Code # 3:

Daemon streams cannot be merged. However, they are destroyed automatically when the main thread exits. Apart from the two operations shown, there are not many other things related to threads. For example, there are no operations to terminate the thread, signal the thread, set up its scheduling, or perform any other high-level operations. To have these features, create them yourself. To be able to terminate streams, the stream must be programmed to poll
exit at selected points. For example, put your stream in a class like the one mentioned in the code below —

Code # 4: Putting a stream in a class.

t = Thread (target = countdown, args = ( 10 ,), daemon = True )

t.start ()

class CountdownTask:

 

def __ init __ ( self ):

  self ._ running = True

 

def terminate ( self ):

self ._ running = False

  

def run ( self , n):

while self ._ running and n & gt;  0 :

print ( `T-minus` , n)

n - = 1

time.sleep ( 5 )

 

c = CountdownTask ()

t = Thread (target = c.run, args = ( 10 ,))  

t.start ()
...
# Termination signal
c.terminate () 

 
# Waiting for actual completion (if necessary)
t.join () 

Polling for thread completion can be difficult to coordinate if threads are performing blocking operations such as typing / output. For example, a thread that is blocked indefinitely on an I / O operation may never return to check if it has been destroyed. To properly handle this case, the thread must be carefully programmed to use timeout loops as shown in the code below.

Code # 5:

class IOTask:

  def terminate ( self ) :

self ._ running = False

 

def run ( self , sock):

  # sock is a socket

 

  # Set the timeout period

  sock.settimeout ( 5

  while self ._ running:

 

# Block input- output with timeout

try :

data = sock.recv ( 8192 )

  break

except socket.timeout:

continue

# Continue processing

...

# Discontinued

  return

Due to the global interpreter locking (GIL), Python threads are limited by the execution model, which allows only one thread in the interpreter to execute at any one time. moment of time. For this reason, Python threads should generally not be used for computationally intensive tasks that require parallelism across multiple processors. They are much better suited for handling I / O and concurrent execution in code that performs blocking operations (e.g., waiting for I / O, waiting for results from the database, etc.).

Code # 6: Streams defined by inheriting from the Thread class

from threading import Thread

 

class CountdownThread (Thread):

def __ init __ ( self , n):

  super () .__ init __ ()

  self . n = 0

 

  def run ( self ):

  while self . n & gt;  0

print ( `T-minus` , self . n)

self . n - = 1

  time. sleep ( 5 )

 

c = CountdownThread ( 5 )

c.start ()

While this works, it introduces additional dependencies b between the code and the threading library. That is, only the resulting code can be used in the context of streams, whereas the method shown earlier involves writing code without an explicit dependency on streams. By freeing your code from such dependencies, it becomes usable in other contexts, which may or may not include threads. For example, you can execute the code in a separate process using a multiprocessor module using the code below:

Code # 7:

import multiprocessing

c = CountdownTask ( 5 )

p = multiprocessing.Process (target = c.run)

p.start ()
...

Again, this only works if the CountdownTask class was written in a way that is neutral to the actual means of concurrency (threads, processes, etc.).