The Python thread is detailed

Source: Internet
Author: User
Tags count instance method join semaphore sleep terminates thread in python

This article mainly introduces the Python thread, this article explains all aspects of threading knowledge, such as thread basic knowledge thread state, thread synchronization (lock), thread communication (condition variable) and so on, need friends can refer to the following

1. Thread Basics

1.1. Thread state

The thread has 5 states, and the process of state conversion is shown in the following illustration:

1.2. Thread Sync (lock)

The advantage of multithreading is that you can run multiple tasks at the same time (at least it feels that way). However, when a thread needs to share data, there may be a problem with data synchronization. Consider a situation where all elements in a list are 0, and the thread "set" changes all elements from the back to 1, while thread "print" is responsible for reading the list and printing it backwards. Then, when the thread "set" starts to change, the thread "print" Prints the list, and the output becomes half 01 and a 1, which is the data's different steps. In order to avoid this situation, the concept of lock is introduced.

There are two states of a lock-locked and unlocked. Whenever a thread such as "set" wants to access the shared data, the lock must first be obtained, and if there are other threads such as "print" that are locked, then the thread "set" is paused, which means the synchronization is blocked, and the thread "set" continues after the thread "print" is accessed and the lock is released. After this processing, the print list is either full output 0, or all output 1, no more than half 1 and a half 1 embarrassing scene.

The interaction between threads and locks is shown in the following illustration:

1.3. Thread communication (condition variable)

Yet there is another awkward situation: The list is not in the beginning; it is created by thread "create." An exception occurs if "set" or "print" accesses the list when "create" is not running. Using locks solves this problem, but "set" and "print" will require an infinite loop-they do not know when "create" will run, let "create" after running to notify "set" and "print" is clearly a better solution. Then, the conditional variable is introduced.

A condition variable allows threads such as "set" and "print" to wait when the condition is not satisfied (the list is none). Wait until the condition is satisfied (the list has been created) to send a notice telling the "set" and "print" conditions are already available, you should get up and work; then the "Set" and " Print "continues to run.

The interaction between a thread and a condition variable is shown in the following illustration:

1.4. Thread running and blocking state transitions

Finally, take a look at the transition of thread running and blocking state.

There are three types of blocking:

Synchronous blocking refers to the state of competitive locking, when the thread requests the lock, it will enter this state, once the lock has been successfully restored to the running state;

Wait for blocking refers to waiting for other threads to notify the state, the thread gets the condition lock, call "Wait" will enter this state, once the other threads give notice, the thread will enter the synchronized blocking state, again competitive condition lock;

Other blocking refers to blocking when calling Time.sleep (), Anotherthread.join (), or waiting for IO, which does not release the acquired lock.

Tips: If you can understand the content, the next topic will be very easy, and the content is the same in most popular programming languages. (meaning is to understand not to >_< too low author level to find someone else's tutorial to understand)

2. Thread

Python provides thread support through two standard library thread and threading. Thread provides low-level, raw threads, and a simple lock.

The code is as follows:

# Encoding:utf-8

Import Thread

Import time

# a function to be executed in a thread

def func ():

For I in range (5):

print ' func '

Time.sleep (1)

# End Current Thread

# This method is equivalent to Thread.exit_thread ()

Thread.exit () # When Func returns, the thread will also end

# Start a thread, the thread starts running immediately

# This method is equivalent to Thread.start_new_thread ()

# The first parameter is the method, and the second parameter is the parameter of the method

Thread.start_new (func, ()) # method requires incoming NULL when no parameters are available tuple

# Create a lock (LockType, not directly instantiated)

# This method is equivalent to Thread.allocate_lock ()

Lock = Thread.allocate ()

# to determine whether the lock is locked or released

Print lock.locked ()

# locks are typically used to control access to shared resources

Count = 0

# Acquire Lock, return true after successful lock acquisition

# Optional Timeout parameter will block until lock is not filled

# Otherwise the timeout will return false

If Lock.acquire ():

Count + 1

# release Lock

Lock.release ()

# The threads provided by the thread module will end at the same time as the main thread ends

Time.sleep (6)

Other methods provided by the thread module:

Thread.interrupt_main (): Terminates the main thread in other threads.

Thread.get_ident (): Gets a magic number representing the current thread, often used to get thread-related data from a dictionary. The number itself has no meaning and will be reused by the new thread when the thread is finished.

Thread also provides a threadlocal class for managing thread-related data, which is referenced in the name thread._local,threading.

Because thread provides a few threads, it is not possible to continue running after the main thread is finished, not to provide conditional variables and so on, the thread module is generally not used, here is not more.

3. Threading

Threading Java-based threading model design. Locks (lock) and condition variables (Condition) are the basic behavior of objects in Java (each object has its own lock and condition variable), while in Python it is a separate object. Python thread provides a subset of the behavior of Java thread; There is no priority, thread group, and thread cannot be stopped, paused, recovered, interrupted. Some of the Java thread's static methods implemented in Python are provided in the form of modular methods in threading.

The common methods provided by the threading module are:

Threading.currentthread (): Returns the current thread variable.

Threading.enumerate (): Returns a list containing the running thread. Running refers to threads that start and end after the thread has started, not including before and after the start.

Threading.activecount (): Returns the number of threads running, with the same result as Len (Threading.enumerate ()).

Classes provided by the threading module:

Thread, Lock, Rlock, Condition, [Bounded]semaphore, Event, Timer, Local.

3.1. Thread

Thread is a threading class, similar to Java, with two ways of using it, passing directly to the method to run or inheriting from thread and overwriting run ():

The code is as follows:

# Encoding:utf-8

Import threading

# method 1: The method to be executed is passed as a parameter to the thread construction method

def func ():

print ' func () passed to Thread '

t = Threading. Thread (Target=func)

T.start ()

# Method 2: Inherit from thread, and rewrite run ()

Class Mythread (threading. Thread):

def run (self):

print ' Mythread extended from Thread '

t = Mythread ()

T.start ()

Construction Method:

Thread (Group=none, Target=none, Name=none, args= (), kwargs={})

Group: Thread Group, currently not implemented, the library reference must be a hint of none;

Target: The method to be executed;

Name: thread name;

Args/kwargs: The arguments to pass in the method.

Instance method:

IsAlive (): Returns whether the thread is running. Running refers to the start, before termination.

Get/setname (name): Gets/sets the thread name.

Is/setdaemon (BOOL): Gets/Sets whether the daemon is a thread. The initial value is inherited from the thread that created the thread. When no non-daemon thread is still running, the program terminates.

Start (): Start the thread.

Join ([timeout]): The thread that blocks the current context environment until the thread calling this method terminates or arrives at the specified timeout (optional parameter).

An example of using join ():

The code is as follows:

# Encoding:utf-8

Import threading

Import time

def context (Tjoin):

print ' in Threadcontext. '

Tjoin.start ()

# will block Tcontext until Threadjoin terminates.

Tjoin.join ()

# Tjoin continues execution after termination.

print ' Out Threadcontext. '

def join ():

print ' in Threadjoin. '

Time.sleep (1)

print ' Out threadjoin. '

Tjoin = Threading. Thread (Target=join)

Tcontext = Threading. Thread (Target=context, args= (Tjoin,))

Tcontext.start ()

Run Result:

The code is as follows:

In Threadcontext.

In Threadjoin.

Out Threadjoin.

Out Threadcontext.

3.2. Lock

Lock (Instruction Lock) is the lowest level of synchronization instruction available. When lock is locked, it is not owned by a particular thread. Lock contains two states-locking and non-locking, and two basic methods.

You can think that lock has a lock pool, and when a thread requests a lock, the thread is in the pool until it gets locked out of the pool. The threads in the pool are in a synchronized blocking state in the Statechart diagram.

Construction Method:

Lock ()

Instance method:

Acquire ([timeout]): Causes the thread to enter a synchronized blocking state, attempting to acquire a lock.

Release (): Releases the lock. The use of a thread must have been locked or an exception will be thrown.

The code is as follows:

# Encoding:utf-8

Import threading

Import time

data = 0

Lock = Threading. Lock ()

def func ():

Global Data

print '%s acquire lock ... '% threading.currentthread (). GetName ()

# when calling acquire ([timeout]), the thread will always block,

# until the lock is obtained or until timeout seconds (timeout parameter optional).

# returns whether a lock is obtained.

If Lock.acquire ():

print '%s get the lock. '% Threading.currentthread (). GetName ()

Data + + 1

Time.sleep (2)

Print '%s release lock ... '% threading.currentthread (). GetName ()

# calling release () releases the lock.

Lock.release ()

T1 = Threading. Thread (Target=func)

T2 = Threading. Thread (Target=func)

T3 = Threading. Thread (Target=func)

T1.start ()

T2.start ()

T3.start ()

3.3. Rlock

A rlock (Reentrant lock) is a synchronization instruction that can be requested multiple times by the same thread. Rlock uses the concept of "owning threads" and "recursive Rank", and Rlock is owned by a thread while in a locked state. The thread that owns the Rlock can call acquire () again, and the same number of releases () will be invoked when the lock is released.

It can be considered that rlock contains a lock pool and a counter with an initial value of 0, each time the acquire ()/release () is successfully invoked, the counter is +1/-1, and the lock is unlocked for 0 o'clock.

Construction Method:

Rlock ()

Instance method:

Acquire ([timeout])/release (): Similar to lock.

The code is as follows:

# Encoding:utf-8

Import threading

Import time

Rlock = Threading. Rlock ()

def func ():

# The first time you request a lock

print '%s acquire lock ... '% threading.currentthread (). GetName ()

If Rlock.acquire ():

print '%s get the lock. '% Threading.currentthread (). GetName ()

Time.sleep (2)

# Second Request lock

print '%s acquire lock again ... '% threading.currentthread (). GetName ()

If Rlock.acquire ():

print '%s get the lock. '% Threading.currentthread (). GetName ()

Time.sleep (2)

# Unlock the locks for the first time

Print '%s release lock ... '% threading.currentthread (). GetName ()

Rlock.release ()

Time.sleep (2)

# Second Release lock

Print '%s release lock ... '% threading.currentthread (). GetName ()

Rlock.release ()

T1 = Threading. Thread (Target=func)

T2 = Threading. Thread (Target=func)

T3 = Threading. Thread (Target=func)

T1.start ()

T2.start ()

T3.start ()

3.4. Condition

Condition (condition variable) is usually associated with a lock. When you need to share a lock in multiple contidion, you can pass a Lock/rlock instance to the construction method, or it will generate a rlock instance of itself.

It can be considered that, in addition to the lock pool with lock, condition also contains a wait pool in which the thread in the pool waits for a blocking state until another thread calls the Notify ()/notifyall () notification, and the thread enters the lock pool waiting to be locked after being notified.

Construction Method:

Condition ([Lock/rlock])

Instance method:

Acquire ([timeout])/release (): the appropriate method to invoke the associated lock.

Wait ([timeout]): Calling this method will cause the thread to enter the condition waiting pool for notification and release the lock. The use of a thread must have been locked or an exception will be thrown.

Notify (): Calling this method will pick a thread from the waiting pool and notify that the thread receiving the notification will automatically call acquire () to try to get the lock (into the lock pool); Other threads are still waiting in the pool. Calling this method does not release the lock. The use of a thread must have been locked or an exception will be thrown.

Notifyall (): Calling this method will notify all threads in the waiting pool that these threads will enter the lock pool to try to acquire a lock. Calling this method does not release the lock. The use of a thread must have been locked or an exception will be thrown.

Examples are the most common producer/consumer models:

The code is as follows:

# Encoding:utf-8

Import threading

Import time

# Merchandise

Product = None

# condition Variable

Con = threading. Condition ()

# producer Methods

def produce ():

Global product

If Con.acquire ():

While True:

If product is None:

print ' Produce ... '

Product = ' anything '

# Inform consumers that the goods have been produced

Con.notify ()

# Waiting to be notified

Con.wait ()

Time.sleep (2)

# Consumer Methods

def consume ():

Global product

If Con.acquire ():

While True:

If product is not None:

print ' Consume ... '

Product = None

# inform the producer that the goods are gone

Con.notify ()

# Waiting to be notified

Con.wait ()

Time.sleep (2)

T1 = Threading. Thread (Target=produce)

T2 = Threading. Thread (Target=consume)

T2.start ()

T1.start ()

3.5. Semaphore/boundedsemaphore

Semaphore (semaphore) is one of the oldest synchronization instructions in the history of computer science. Semaphore manages a built-in counter that, whenever acquire () is invoked-1, calls release () at +1. The counter cannot be less than 0, and when the counter is 0 o'clock, acquire () blocks the thread to the synchronized lock state until the other thread invokes release ().

Based on this feature, semaphore is often used to synchronize some objects with a "visitor cap", such as a connection pool.

The only difference between Boundedsemaphore and semaphore is that the former will check that the value of the counter exceeds the counter's initial value when the release () is invoked, and an exception is thrown if it is exceeded.

Construction Method:

Semaphore (value=1): value is the initial value of the counter.

Instance method:

Acquire ([timeout]): request semaphore. If the counter is 0, the thread is blocked to the synchronized blocking state, otherwise the counter-1 is returned immediately.

Release (): Releases the semaphore, counters +1, and if Boundedsemaphore is used, the number of releases is checked. The release () method does not check whether the thread has obtained semaphore.

The code is as follows:

# Encoding:utf-8

Import threading

Import time

# Counter initial value is 2

Semaphore = Threading. Semaphore (2)

def func ():

# request semaphore, after success counter-1; counter is blocked 0 o'clock

print '%s acquire semaphore ... '% threading.currentthread (). GetName ()

If Semaphore.acquire ():

print '%s get semaphore '% threading.currentthread (). GetName ()

Time.sleep (4)

# release semaphore, counter +1

Print '%s release semaphore '% Threading.currentthread (). GetName ()

Semaphore.release ()

T1 = Threading. Thread (Target=func)

T2 = Threading. Thread (Target=func)

T3 = Threading. Thread (Target=func)

T4 = Threading. Thread (Target=func)

T1.start ()

T2.start ()

T3.start ()

T4.start ()

Time.sleep (2)

# The main thread that does not get Semaphore can also call release

# throws an exception if you use BOUNDEDSEMAPHORE,T4 to release semaphore

print ' Mainthread release semaphore without acquire '

Semaphore.release ()

3.6. Event

Event is one of the simplest threading mechanisms: one thread notifies an event, and another thread waits for the event. The event has a built-in flag that is initially false, set to True when the set () is invoked, and reset to False when the clear () is invoked. Wait () will block the thread until it waits for a blocking state.

Event is actually a simplified version of the Condition. The event has no lock and cannot cause the thread to enter a synchronized blocking state.

Construction Method:

Event ()

Instance method:

IsSet (): Returns True when the built-in flag is true.

Set (): Sets the flag to true and notifies all threads waiting to be blocked to resume running.

Clear (): Sets the flag to false.

Wait ([timeout]): If the flag returns immediately if it is true, it will block the thread until it waits for the blocking state, waiting for the other thread to call set ().

The code is as follows:

# Encoding:utf-8

Import threading

Import time

event = Threading. Event ()

def func ():

# Wait for the event, enter the wait-blocking state

print '%s ' Wait for event ... '% threading.currentthread (). GetName ()

Event.wait ()

# Enter the running state after receiving the event

print '%s recv event. '% Threading.currentthread (). GetName ()

T1 = Threading. Thread (Target=func)

T2 = Threading. Thread (Target=func)

T1.start ()

T2.start ()

Time.sleep (2)

# Send Event notification

print ' Mainthread set event. '

Event.set ()

3.7. Timer

A timer (timer) is a derived class of thread that is used to invoke a method after a specified time.

Construction Method:

Timer (interval, function, args=[], kwargs={})

Interval: Specified time

Function: Method to execute

Args/kwargs: Parameter of method

Instance method:

The timer derives from thread without adding an instance method.

The code is as follows:

# Encoding:utf-8

Import threading

def func ():

print ' Hello timer! '

Timer = Threading. Timer (5, func)

Timer.start ()

3.8. Local

A local is a class that starts with a lowercase letter and is used to manage thread-local (thread-partial) data. For the same local, the thread cannot access the properties set by the other thread; The properties set by the thread are not replaced by the same name as the other thread set.

You can think of local as a "threading-Attribute Dictionary" dictionary, where local encapsulates the details of retrieving the corresponding property dictionary from its own thread as a key, and then using the property name as the key to retrieve the property value.

The code is as follows:

# Encoding:utf-8

Import threading

Local = Threading.local ()

Local.tname = ' main '

def func ():

Local.tname = ' Notmain '

Print Local.tname

T1 = Threading. Thread (Target=func)

T1.start ()

T1.join ()

Print Local.tname

Mastering thread, Lock, and condition can deal with most situations where threads are needed, and in some cases local is also very useful. This article concludes by using these classes to show the scenarios mentioned in the thread base:

Copy code code as follows:

# Encoding:utf-8

Import threading

Alist = None

Condition = Threading. Condition ()

Def doset ():

If Condition.acquire ():

While Alist is None:

Condition.wait ()

For I in range (len (alist)) [::-1]:

Alist[i] = 1

Condition.release ()

Def doprint ():

If Condition.acquire ():

While Alist is None:

Condition.wait ()

For I in Alist:

Print I,

Print

Condition.release ()

Def docreate ():

Global Alist

If Condition.acquire ():

If Alist is None:

Alist = [0 for I in range (10)]

Condition.notifyall ()

Condition.release ()

Tset = Threading. Thread (target=doset,name= ' Tset ')

Tprint = Threading. Thread (target=doprint,name= ' Tprint ')

Tcreate = Threading. Thread (target=docreate,name= ' tcreate ')

Tset.start ()

Tprint.start ()

Tcreate.start ()

Complete Full text

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.