python multithreading
There are two ways to implement multithreading in Python, a start_new_thread () function based on the _thread module (the thread module in the python2.x version, without an underscore), and a thread class based on the threading module.
In fact, Python's multithreaded programming does not really take advantage of multicore CPUs, but using open source modules to distribute your computational pressure on multicore CPUs ...
I. Using Start_new_thread () to implement threads is a relatively low-level implementation, where all threads share their global data, and in order to achieve synchronization, the module also provides a simple locking mechanism
| _thread.start_new_thread (function, args[, Kwargs]) |
| Starts a new process and returns its identifier. The parameters required by a thread's execution are provided by args (which must be a tuple), or a dictionary of keyword parameters can be supplied with the optional parameter Kwargs. When the function returns, the thread that is started also stops exiting. If an unhandled exception exists in the function, the thread stops exiting after the stack trace is printed (other threads continue to execute). |
Where the thread identifier is a non-0 integer, and there is no direct meaning, can be used as a special dictionary from a thread to index the key of this thread, can also be obtained by _thread.get_ident (), the identifier will be reclaimed by the system after thread exit. The execution of this thread can be terminated by calling _thread.exit () during the course execution.
Java code
- Import _thread
- Import time
- def threadfunction (count):
- For I in range (count):
- Print (' printing%d ' of process ID%d '% (_thread.get_ident (), i))
- i-=1
- Time.sleep (0.1)
- Def begin ():
- Ident1=_thread.start_new_thread (threadfunction, (+) )
- Print (' process ' with start identifier%d '% (ident1,))
- Ident2=_thread.start_new_thread (threadfunction, (+) )
- Print (' process ' with start identifier%d '% (Ident2,))
- if __name__ = = ' __main__ ':
- Begin ()
Two. Using the thread class to implement multithreading is a high-level encapsulation of the _thread module (dummy_threading, if not _thread), in which case we need to create a new class to inherit threading. Thread, overriding threading like Java. Thread's Run method. Starts the thread with the thread's Start method, which invokes the Run method we have rewritten.
Java code
- Class MyThread (threading. Thread):
- " can only rewrite __init__ and run two methods"
- def __init__ (self,name):
- Threading. Thread.__init__ (self)
- Self.name=name
- Self.bool_stop=false
- def run (self):
- While not Self.bool_stop:
- Print (' process%s, at%s '% (Self.name,time.asctime ()))
- Time.sleep (1)
- def stop (self):
- Self.bool_stop = True
- if __name__ = = ' __main__ ':
- Th1=mythread (' one ')
- Th2=mythread (' both ')
- Th1.start ()
- Th2.start ()
The thread class also defines the following common methods and properties:
| Thread.getname () \thread.setname () |
| The old way to get and set the name of the thread, the official suggested replacing it with Thread.Name |
| Thread.ident |
| Gets the identifier of the thread. Only valid after the call to start () method is executed, otherwise none is returned. |
| Thread.is_alive () |
| Determines whether the thread is active. |
| Thread.Join ([timeout]) |
| Calling Thread.Join will cause the thread to block until the calling thread finishes running or times out. The parameter timeout is a numeric type that indicates the time-out period, and if the parameter is not supplied, the thread will block until the thread ends. |
locks in Python
Using the lock lock of the _thread module to realize the problem of producer consumers, the lock object is a low-level line programming tool provided by Python, it is very simple to use, just the following 3 statements:
| _thread.allocate_lock () returns a new lock object, which is a new |
| Lock.acquire () equals p operation, gets a lock, |
| Lock.release () is equivalent to V operation, releasing a lock |
The code is as follows:
Java code
- Import _thread,time,random
- dish=0
- Lock = _thread.allocate_lock ()
- Def producerfunction ():
- "If you cast a sieve larger than 0.2, add an apple to the plate ."
- Global Lock,dish
- While True:
- if (Random.random () > 0.1):
- Lock.acquire ()
- if dish < :
- dish+=1
- Print (' producer adds an Apple, now has%d apples '% (dish,))
- Lock.release ()
- Time.sleep (Random.random () *3)
- Def consumerfunction ():
- "If you cast a sieve larger than 0.5, take an apple from the plate ."
- Global Lock,dish
- While True:
- if (Random.random () > 0.9):
- Lock.acquire ()
- if dish > 0:
- dish-=1
- Print (' Consumers take an apple now, there are%d apples '% (dish,)
- Lock.release ()
- Time.sleep (Random.random () *3)
- Def begin ():
- Ident1=_thread.start_new_thread (Producerfunction, ())
- Ident2=_thread.start_new_thread (Consumerfunction, ())
- if __name__ = = ' __main__ ':
- Begin ()
Another higher-level lock is a rlock lock, and the Rlock object maintains a lock object inside it, which is a Reentrant object. For a lock object, if a thread acquire the operation two times in a row, the second acquire will suspend the thread because there is no release after the first acquire. This causes the lock object to never release, causing the thread to deadlock. The Rlock object allows a thread to acquire its operations multiple times, because the number of threads acquire is maintained internally through a counter variable. And each time the acquire operation must have a release operation corresponding to it, after all the release operation is completed, the other thread can request the Rlock object.
The threading module is also available and encapsulated for lock, providing a more advanced way of synchronizing (which can be understood as a more advanced lock), including threading. Event and Threading.condition, where threading.event provides a simple way to synchronize: One process flags the event, the other processes wait, just a few of the following methods:
| Event.wait ([timeout]) |
| The thread is blocked until the event object's internal identity bit is set to true or timed out (if parameter timeout is provided). |
| Event.set () |
| Set the identification number to Ture |
| Event.clear () |
| Set as identifier false |
Threading. Condition can interpret condiftion as a high-level lock, which provides more advanced functionality than locks, Rlock allows us to control complex thread synchronization issues. Threadiong. Condition maintains a trivial object internally (by default, Rlock), which can be passed in as a parameter when creating a Condigtion object. Condition also provides acquire, release method, its meaning and the acquire, release method consistent, in fact, it is simply a simple call inside the corresponding method of the object. Condition also provides the following methods (especially note: These methods can only be called after the acquire), otherwise the runtimeerror exception will be reported. ):
| Condition.wait ([timeout]): |
| The Wait method releases the internal footprint, and the thread is suspended until the notification is woken up or timed out (if the timeout parameter is provided). The program will continue to execute when the thread is awakened and re-occupied. |
| Condition.notify (): |
| Wakes up a suspended thread (if there is a pending thread). Note: the Notify () method does not release the occupied locks. |
| Condition.notify_all () |
| Wakes all pending threads (if there are pending threads). Note: These methods do not release the locks that are occupied. |
Python multi-threaded and Python locks