Python implements multithreading primarily through the threading package in the standard library.
In today's network era, every server receives a large number of requests. The server can handle these requests in a multi-threaded manner to improve the read and write efficiency of the network ports.
Python is a Web server's background working language (such as Douban), so multithreading is naturally supported by the Python language.
Multi-threaded ticketing and synchronization we use Python to implement the ticketing procedures in Linux multi-threading and synchronization.
We use a mutex (that is, the lock class object in Python) to implement thread synchronization:
Import Threadingimport Timeimport os# This function could is called by any function to does other Chores.def Dochore (): t Ime.sleep (0.5) # Function for each threaddef booth (TID): Global I Global lock while True:lock.acquire () # Lock; Or wait if other thread is holding the lock if I! = 0:i = i-1 # Sell Tickets Print (TID, ': Now left: ', i) # Tickets left Dochore () # Other critical operations else: Print ("thread_id", Tid, "No more Tickets") Os._exit (0) # exit the whole process Immediat Ely Lock.release () # Unblock Dochore () # non-critical operations# Start of The main functioni = # Available Ticket Number lock = Threading. Lock () # lock (i.e., mutex) # Start Threadsfor K in range: New_thread = Threading. Thread (target=booth,args= (k,)) # Set up threAd Target:the callable (function) to is run, args:the argument for the callable New_thread.start () # Run the thread
There are two global variables, one is I, to store the remaining votes, and one is the lock object, which is used to synchronize the modification of the thread to I.
In addition, in the final for loop, we set up a total of 10 threads. Each thread executes the booth () function.
The thread is formally started when the start () method is called (in fact, there are up to 11 threads in the computer, because the main program itself consumes one thread).
Python uses the Threading.thread object to represent the thread and uses the Threading.lock object to represent a mutex (mutex).
There are two points to note:
We use global in our functions to declare variables as global variables, allowing multithreading to share I and lock (in C, we make it a global variable by placing variables out of all functions).
If you do not declare this, because I and lock are immutable data objects, they will be treated as a local variable.
If it is a mutable data object, then the global declaration is not required. We can even pass a mutable data object as a parameter to the thread function.
These threads will share these mutable data objects. We used two dochore () functions in booth.
The program can be improved in the future to allow threads to do more than i=i-1, such as printing the remaining votes, making money, or drinking saliva.
The first Dochore () is still inside lock, so it is safe to use shared resources (critical operations, such as printing the remaining votes).
At the second dochore (), lock has been released, so it is no longer possible to use a shared resource.
This is where you can do things that don't use shared resources (Non-critical operation, like change, water).
Here deliberately let Dochore () wait 0.5 seconds to represent the time that these extra operations might take. You can define the function to replace Dochore ().
The Python program above the OOP creation thread is very similar to a procedure-oriented C program. Here we describe how to implement multi-threading through an object-oriented approach, with the core of inheriting threading. Thread class.
Import threadingimport timeimport os def dochore (): Time.sleep (0.5) # Function for each threadclass booththread (Threadi Ng. Thread): Def __init__ (self, Tid, monitor): Self.tid = tid self.monitor = Monitor Threadin G.thread.__init__ (self) def run (self): while true:monitor[' Lock '].acquire () # Lock; Or wait if other thread is holding the lock if monitor[' tick ']! = 0:monitor[' tick '] = monitor[' Tick ']-1 # Sell Tickets print (Self.tid, ': Now left: ', monitor[' Tick ']) # tickets left Dochore () # Other critical Operations Else:print ("Thr Ead_id ", Self.tid," No more Tickets ") Os._exit (0) # exit the whole proces s immediately monitor[' lock '].release () # Unblock Dochore () # non-critical Operations # Start of the main functionmonitor = {' Tick ': +, ' Lock ': Threading. Lock ()} # Start ten threadsfor K in range: New_thread = Booththread (k, monitor) New_thread.start ()
Threading has been used in the for loop above. The thread () method creates a thread object and passes the function booth () and its arguments to the modified object, and calls the start () method to run the thread.
OOP, you define the command that the thread executes by modifying the run () method of the thread class.
You define a class Booththread, which inherits from thread. Threading class.
We then put the actions of the above booth () into the run () method of the Booththread class.
Note that instead of using global variables to declare the global variable, we use a dictionary monitor to store the globals and then pass the dictionary as a parameter to the thread function.
Since the dictionary is a mutable data object, when it is passed to the function, the function is still using the same object, which is equivalent to being shared by multiple threads.
This is also a technique for multithreading and even multi-process programming (you should try to avoid the use of the global declaration above as it does not apply to the Windows platform).
There is no significant difference between OOP programming methods and process-oriented programming methods.
Other threading. Thread object, we have introduced the object's start () and run (), in addition:
Join () method
The thread that calls the method waits until it is finished with the thread object, and then resumes running. This is similar to calling the wait () function between processes.
The following objects are used to handle multi-threaded synchronization. Once an object is created, it can be shared by multiple threads and block certain processes as appropriate.
Threading. Lock Object
Mutex, with the acquire () and release () methods.
Threading. Condition Object
Condition variable, when the object is created, it contains a lock object (because condition variable is always used with the mutex).
You can call the acquire () and release () methods on the condition object to control the potential lock object.
Wait () method
Equivalent to Cond_wait ()
Notify_all ()
Quite with Cond_broadcast ()
Nofify ()
Similar to the Notify_all () feature, but only wakes up a waiting thread, not all
Threading. Semaphore Object
Semaphore, which is the count lock. When creating an object, you can pass an integer as the upper limit of the count (Sema = threading. Semaphore (5)).
It is similar to lock and has two methods for lock.
Threading. Event Object
With threading. The condition is similar to the condition variable without the potential lock protection.
The object has a status of true and false two. You can use Wait () waits for multiple threads until a thread calls the object's set () method and sets the object to True.
A thread can call the object's clear () method to reset the object to a false state.
# The last few chapters don't look too clear ~~~~~
Python Learning Note 16: Standard library multi-Threading (threading package)