Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Python Low-level threading API
The _thread module in Python provides a low-level interface for working with lightweight processes having multiple threads sharing a global data space. For synchronization, simple locks (also called mutexes or binary semaphores) are defined in this module. The threading built-in module provides a higher-level threading API built on top of this module.
start_new_thread() Function
This module-level function is used to open a new thread in the current process. The function takes a function object as an argument. This function gets invoked on successful creation of the new thread. The span of this function corresponds to the lifespan of the thread.
Example
Following code is a simple example of thread mechanism using the _thread module ?
import _thread
import time
def run(threadName):
count = 0
for i in range(1, 6):
time.sleep(5)
print(threadName, i)
_thread.start_new_thread(run, ("child", ))
for i in range(1, 6):
print("main", i)
time.sleep(5)
The start_new_thread() function spawns a new thread which calls run() function parallelly. There is a loop in the run() function as well as in the main thread of the program. Call to sleep() function in both results in overlapped execution as shown below ?
main 1 child 1 main 2 child 2 main 3 child 3 main 4 child 4 main 5 child 5
Thread Synchronization with Locks
The inter-thread synchronization is achieved by using the Lock object. The allocate_lock() function returns a lock object. Following methods are available for it ?
acquire() Method
This method acquires the lock unconditionally until it is released by another thread. Only one thread at a time can acquire a lock. The return value is True if the lock is acquired successfully, False if not.
release() Method
This method releases the lock. The lock must have been acquired earlier, but not necessarily by the same thread.
Example with Lock
In the following example, two threads are declared. Each invokes run() function concurrently. One of them acquires the lock and proceeds to enter synchronized() function while the other waits ?
import _thread
import time
def run(threadName):
lock.acquire()
synchronized(threadName)
lock.release()
def synchronized(threadName):
print(threadName, "has acquired lock")
counter = 10
while counter:
time.sleep(1)
print("*", end="")
counter = counter - 1
print("\n{} has released lock".format(threadName))
lock = _thread.allocate_lock()
_thread.start_new_thread(run, ("t1", ))
_thread.start_new_thread(run, ("t2", ))
# Keep main thread alive
time.sleep(30)
t1 has acquired lock ********** t1 has released lock t2 has acquired lock ********** t2 has released lock
Key Points
- The
_threadmodule provides low-level threading primitives - Use
start_new_thread()to create new threads - Locks prevent race conditions between threads
- Always release acquired locks to avoid deadlock
- The higher-level
threadingmodule is recommended for most applications
Conclusion
The _thread module provides basic threading functionality with start_new_thread() for thread creation and locks for synchronization. For most applications, the higher-level threading module is preferred over this low-level interface.
