Python: Threads

Source: Internet
Author: User
Tags posix

The python thread is the real POSIX thread, not the simulated thread.

Python's Standard library provides two modules: _thread and threading , is the _thread low-level module, threading is the advanced module, the _thread Encapsulation. In most cases, we only need to use threading this advanced module.

Starting a thread is to pass a function in and create an Thread instance, and then call to start() start executing:

Importtime , Threading#code executed by the new thread:defLoop ():Print('thread%s is running ...'%threading.current_thread (). name) n=0 whileN < 5: N= n + 1Print('thread%s >>>%s'%(threading.current_thread (). name, n)) time.sleep (1)    Print('thread%s Ended.'%threading.current_thread (). Name)Print('thread%s is running ...'%threading.current_thread (). Name) t= Threading. Thread (target=loop, name='Loopthread') T.start () t.join ()Print('thread%s Ended.'% Threading.current_thread (). Name)

Execution results

is is>>> 1>>> 2 >>>3 >> > 4>>> 5thread loopthread ended.thread mainthread ended.

Analysis

Since any process will start a thread by default, we call it the main thread, the main thread can start new threads, and the Python threading module has a current_thread() function that always returns an instance of the current Thread. The name of the main thread instance is called, the name of the MainThread child thread is specified at creation time, and we use the LoopThread named child Thread. The name is only used to display when printing, there is absolutely no other meaning, if not the name of Python automatically named to Thread-1 the thread, Thread-2 ...

Lock

The biggest difference between multithreading and multi-process is that, in many processes, the same variable, each one copy is in each process, does not affect each other, and in many threads, all variables are shared by all threads, so any one variable can be modified by any one thread, so, The biggest danger of sharing data between threads is that multiple threads change a variable at the same time, and the content is Scrambled.

Importtime , Threading#Suppose this is your bank deposit:Balance =0lock=Threading. Lock ()defchange_it (n):#The result should be 0 if you save it first:    GlobalBalance Balance= Balance +N Balance= balance-NdefRun_thread (n): forIinchRange (100000): lock.acquire ()#to get the lock first:        Try:#change it with Confidence:change_it (n)finally:#change it. Be sure to release the Lock:lock.release () T1= Threading. Thread (target=run_thread, args= (5,)) T2= Threading. Thread (target=run_thread, args= (8,)) T1.start () t2.start () t1.join () t2.join ( )Print(balance)

Analysis

When two threads are saved at the same time, it may cause the balance to be incorrect, and you certainly don't want your bank account to become a negative number somehow, so we have to make sure that when a thread is modified balance , other threads must not change.

If we want to make sure that the balance calculation is correct, we will give change_it() a lock, and when a thread starts executing change_it() , we say that the thread has acquired a lock, so the other thread cannot execute at the same time, change_it() wait until the lock is released, and then the lock can be changed. Since there is only one lock, no matter how many threads, at most one thread at a time holds the lock, so there is no conflict of Modification. Creating a lock is accomplished by threading.Lock() :

Multi-threaded Reading: 107502

Multitasking can be done by multiple processes or by multithreading within a process.

We mentioned earlier that a process is made up of several threads, and a process has at least one thread.

Because threads are execution units that are directly supported by the operating system, high-level languages often have built-in multithreading support, Python is no exception, and Python threads are real POSIX threads, not those that are Emulated.

Python's Standard library provides two modules: _thread and threading , is the _thread low-level module, threading is the advanced module, the _thread Encapsulation. In most cases, we only need to use threading this advanced module.

Starting a thread is to pass a function in and create an Thread instance, and then call to start() start executing:

import time, threading# The code executed by the new thread: def loop (): print ( ' thread%s is running ... '% threading.current_thread (). name) n = 0 while N < 5:n = n + 1 print (1) print ( ' loopthread ') t.start () t.join () print ( ' thread% s ended. '% threading.current_thread (). name)          

The results of the implementation are as Follows:

is running...thread LoopThread is running...thread LoopThread >>> 1thread LoopThread >>> 2thread LoopThread >>> 3thread LoopThread >>> 4thread LoopThread >>> 5thread LoopThread ended.thread MainThread ended.

Since any process will start a thread by default, we call it the main thread, the main thread can start new threads, and the Python threading module has a current_thread() function that always returns an instance of the current Thread. The name of the main thread instance is called, the name of the MainThread child thread is specified at creation time, and we use the LoopThread named child Thread. The name is only used to display when printing, there is absolutely no other meaning, if not the name of Python automatically named to Thread-1 the thread, Thread-2 ...

Lock

The biggest difference between multithreading and multi-process is that, in many processes, the same variable, each one copy is in each process, does not affect each other, and in many threads, all variables are shared by all threads, so any one variable can be modified by any one thread, so, The biggest danger of sharing data between threads is that multiple threads change a variable at the same time, and the content is Scrambled.

Take a look at how multiple threads can manipulate a variable to change the Content:

 import time, threading# Assuming this is your bank deposit: balance = 0def change_it  (n): # First Save and then fetch, the result should be 0: global balance balance = Balance + N balance = Balance-ndef run_thread (n): for i in range (100000): change_it (n) T1 = Threading. Thread (target=run_thread, args= (5,)) t2 = threading. Thread (target=run_thread, args= (8,)) t1.start () t2.start () t1.join () t2.join () Print (balance)  

We define a shared variable balance , the initial value is 0 , and start two threads, save after fetch, theoretically the result should be 0 , however, because the thread scheduling is determined by the operating system, when t1, T2 alternating execution, As long as the number of loops, balance The result is not necessarily 0up.

The reason is because a statement in a high-level language is a few statements when the CPU executes, even if a simple calculation:

balance = balance + n

Also in two steps:

    1. To be calculated balance + n and deposited into a temporary variable;
    2. Assigns the value of the temporary variable balance .

which can be seen as:

x = balance + nbalance = x

Since X is a local variable, two threads each have their own x, when the code executes normally:

  initial value balance = 0t1:x1 = balance +  5 # x1 = 0 + 5 = 5t1:balance = x1 # Balance = 5t1:x1 = Balance-5 # x1 = 5-5 = 0t1:balance = x1 # balance = 0t2:x2 = balance + 8 # x2 = 0 + 8 = 8t2:balance = x2 # balance = 8t2:x2 = Balance-8 # x2 = 8-8 = 0t2:ba Lance = x2 # balance = 0 Result balance = 0      span>                 

But T1 and T2 are run alternately if the operating system executes t1, T2 in the following order:

  initial value balance = 0t1:x1 = balance + 5 # x1 = 0 + 5 = 5t2:x2 = balance + 8 # x2 = 0 + 8 = 8t2:balance = x2 # balance = 8t1:balance = x1 # balance = 5t1:x1 = Balance-5 # x1 = 5-5 = 0t1:balance = x1 # balance = 0t2:x2 = Balance-8 # x2 = 0-8 = -8t2: Balance = x2 # balance =-8 result balance =-8      

The reason is that because the modification balance requires multiple statements, while executing these statements, the thread may break, causing multiple threads to change the contents of the same object.

When two threads are saved at the same time, it may cause the balance to be incorrect, and you certainly don't want your bank account to become a negative number somehow, so we have to make sure that when a thread is modified balance , other threads must not change.

If we want to make sure that the balance calculation is correct, we will give change_it() a lock, and when a thread starts executing change_it() , we say that the thread has acquired a lock, so the other thread cannot execute at the same time, change_it() wait until the lock is released, and then the lock can be changed. Since there is only one lock, no matter how many threads, at most one thread at a time holds the lock, so there is no conflict of Modification. Creating a lock is accomplished by threading.Lock() :

0lock = threading.Lock()def run_thread(n): for i in range(100000): # 先要获取锁: lock.acquire() try: # 放心地改吧: change_it(n) finally: # 改完了一定要释放锁: lock.release()

When multiple threads are executing at the same time lock.acquire() , only one thread can successfully acquire the lock and then continue executing the code, and the other threads continue to wait until the lock is Acquired.

The thread that gets the lock must release the lock after it is exhausted, or the thread that waits for the lock waits forever to become a dead thread. So we use it try...finally to make sure that the lock will be released.

The advantage of the lock is to ensure that a certain section of the key code can only be performed by a single thread from start to finish, the disadvantage is also many, the first is to prevent multi-threaded concurrent execution, a piece of code containing the lock can actually only be executed in single-threaded mode, the efficiency is greatly reduced. second, because multiple locks can exist, different threads hold different locks, and attempting to acquire a lock held by the other side can cause deadlocks, cause multiple threads to hang all, neither execute nor end, only by the operating system to force Termination.

multi-core CPUs

Python: Threads

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.