Python threading introduction

Python threading introduction

What is a Thread?

A thread is the smallest sequence of programmed instructions that can be managed independently by a scheduler, which is a part of the operating system.The implementation of threads and processes differs between operating systems, but in most cases a thread is a component of a process.Multiple threads can exist within one process, executing concurrently and sharing resources such as memory,while different processes do not share these resources.Threads of a process share its executable code and the values of its dynamically allocated variables and non-thread global variables at any given time.

What is Singlethreaded process?

Single threaded processes contain the execution of instructions in a single sequence. In other words,one command is processes at a time. The opposite of single threaded  processes are multithreaded processes. These processes allow the execution of multiple parts of a program at the same time.

What is Multithreaded process?

Multithreading is mainly found in multitasking operating systems. Multithreading is a widespread programming and execution model that allows multiple threads to exist within the context of one process. These threads share the process's resources, but are able to execute independently. The threaded programming model provides developers with a useful abstraction of concurrent execution. Multithreading can also be applied to one process to enable parallel execution on a multiprocessing system.

Benefits of Multi-Threading

Types of Threads?
Mutliple threads within a process share the same data space with the main thread and can therefore share information or communication with each other more easily than if they were seperate processes.Threads are also called as light-weight processes and they do not require much memory overhead,they are cheaper than processes.
It can be pre-empted(interrupted).
It can be temporarily put on hold while other threads are running,this is called yielding.

There are two different kinds of threads:
Kernel threads
User threads

Kernel threads
kernel thread is a "lightweight" unit of kernel scheduling. At least one kernel thread exists within each process. If multiple kernel threads exist within a process, then they share the same memory and file resources. Kernel threads are preemptively multitasked if the operating system's process scheduler is preemptive. Kernel threads do not own resources except for a stack, a copy of the registers including the program counter, thread local storage and are thus relatively cheap to create and destroy. Thread switching is also relatively cheap: it requires a context switch (saving and restoring registers and stack pointer), but does not change virtual memory and is thus cache-friendly (leaving TLB valid). The kernel can assign one thread to each logical core in a system (because each processor splits itself up into multiple logical cores if it supports multithreading, or only supports one logical core per physical core if it does not), and can swap out threads that get blocked. However, kernel threads take much longer than user threads to be swapped.
User threads
Threads are sometimes implemented in user space libraries, thus called user threads. The kernel is unaware of them, so they are managed and scheduled in user space . Some implementations base their user threads on top of several kernel threads, to benefit from multi-processor machines.User threads as implemented by virtual machines are also called green threads. User threads are generally fast to create and manage, but cannot take advantage of multithreading or multiprocessing, and will get blocked if all of their associated kernel threads get blocked even if there are some user threads that are ready to run.

The "threading" Library
The Python standard library provides threading, which contains most of the primitives.Thread, in this module,nicely encapsulates threads,providing a clean interface to work with them. When you create a Thread,you pass it a function and a list containing the arguments to that function.
The "threading" module defines the following functions:
active_count ( ) : Return the number of thread objects that are active.
current_thread ( )  : Return the number of thread object, corresponding to the caller%u2019s thread of control.
excepthook(args/Handle uncaught exception raised by

 The args argument has the following attributes
exc_type: Exception type.
exc_value: Exception value, can be None.
exc_traceback: Exception traceback, can be None.
thread: Thread which raised the exception, can be None.

join(timeout=None):Wait until the thread terminates. This blocks the calling thread until the thread                whose join() method is called terminates either normally or through an unhandled exception or until               the  optional timeout occurs.
get_indent () : Return the thread identifier of the current thread. This is a nonzero integer. Its value has no direct meaning; it is intended as a magic cookie to be used e.g. to index a dictionary of thread-specific data. Thread identifiers may be recycled when a thread exits and another thread is created.
get_native_id() : Return the native integral Thread ID of the current thread assigned by the kernel. This is a non-negative integer. Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS).
enumerate():Return a list of all Thread  objects currently alive. The list includes daemonic threads, dummy thread objects created by current_thread() and the main thread. It excludes terminated threads and threads that have not yet been started.
main_thread() :Return the main Thread object. In normal conditions, the main thread is the thread from which the Python interpreter was started.
settrace(func) :Set a trace function for all threads started from the threading module. The func will be passed to  sys.settrace () for each thread, before its run() method is called.
setprofile(func) :Set a profile function for all threads started from the threading module. The func will be passed to sys.setprofile  ()for each thread, before its run() method  called.
stack_size([size]):Return the thread stack size used when creating new threads. The optional size argument specifies the stack size to be used for subsequently created threads, and must be 0 (use platform or configured default) or a positive integer value of at least 32,768 (32 KiB). If size is not specified, 0 is used. If changing the thread stack size is unsupported, a Runtime error is raised.
start() :Start the threads activity.
run():Method representing the threads activity.
setName() : Old getter/setter API for name, use it directly as a property instead.
is_alive(:Return whether the thread is alive.
setDaemon() :Old getter/setter API for daemon, use it directly as a property instead.
acquire(blocking=Truetimeout=-1) :Acquire a lock, blocking or non-blocking.
release() :Release a lock. This can be called from any thread, not only the thread which has acquired the lock.
wait(timeout=None): Wait until notified or until a timeout occurs. If the calling thread has not acquired the lock when this method is called, a Runtime Error is raised.
wait_for(predicatetimeout=None) :Wait until a condition evaluates to true. predicate should be a callable which result will be interpreted as a boolean value. A timeout may be provided giving the maximum time to wait.
notify(n=1) :By default, wake up one thread waiting on this condition, if any. If the calling thread has not acquired the lock when this method is called, a Runtime Error is raised.
notify_all() : Wake up all threads waiting on this condition. This method acts like notify(), but wakes up all waiting threads instead of one. If the calling thread has not acquired the lock when this method is called, a is Runtime Error is raised.
Semaphore(value=1) :This class implements semaphore objects. A semaphore manages an atomic counter representing the number of  release() calls minus the number of acquire() calls, plus an initial value. The acquire() method blocks if necessary until it can return without making the counter negative. If not given, value defaults to 1.
BoundedSemaphore(value=1) :Class implementing bounded semaphore objects. A bounded semaphore checks to make sure its current value doesn%u2019t exceed its initial value. If it does,  value error is raised. In most situations semaphores are used to guard resources with limited capacity. If the semaphore is released too many times it is  a sign of a bug. If not given, value defaults to 1.
is_set(): Return true if and only if the internal flag is true.
set():Set the internal flag to true. All threads waiting for it to become true are awakened. Threads that call wait() once the flag is true will not block at all.
clear() :Reset the internal flag to false. Subsequently, threads calling wait() will block until set() is called to set the internal flag to true again.
cancel() :Stop the timer, and cancel the execution of the timers action. This will only work if the timer is still in its waiting stage.
Barrier(partiesaction=Nonetimeout=None) :Create a barrier object for parties number of threads. An action, when provided, is a callable to be called by one of the threads when they are released. timeout is the default timeout value if none is specified for the  wait() method.
reset() :Return the barrier to the default, empty state. Any threads waiting on it will receive the BrokenBarrierException exception.
abort() : Put the barrier into a broken state. This causes any active or future calls to wait()  to fail with the BrokenBarrierException. Use this for example if one of the threads needs to abort, to avoid deadlocking the application.