


An in-depth understanding of multithreading in Python. A must-read for newbies
Example 1
We are going to request five different URLs:
Single threaded
import time import urllib2 defget_responses(): urls=[ ‘http://www.baidu.com', ‘http://www.amazon.com', ‘http://www.ebay.com', ‘http://www.alibaba.com', ‘http://www.jb51.net' ] start=time.time() forurlinurls: printurl resp=urllib2.urlopen(url) printresp.getcode() print”Elapsed time: %s”%(time.time()-start) get_responses()
The output is:
http://www.baidu.com200
http://www.amazon.com200
http://www.ebay .com200
http://www.alibaba.com200
http://www.jb51.net200
Elapsed
time:3.0814409256
Explanation:
urls are requested in order
Unless the cpu gets a response from one url, it will not request the next url
The network request will take a long time, so the cpu is waiting for the return time of the network request has been idle.
Multi-threading
import urllib2 import time from threading import Thread classGetUrlThread(Thread): def__init__(self, url): self.url=url super(GetUrlThread,self).__init__() defrun(self): resp=urllib2.urlopen(self.url) printself.url, resp.getcode() defget_responses(): urls=[ ‘http://www.baidu.com', ‘http://www.amazon.com', ‘http://www.ebay.com', ‘http://www.alibaba.com', ‘http://www.jb51.net' ] start=time.time() threads=[] forurlinurls: t=GetUrlThread(url) threads.append(t) t.start() fortinthreads: t.join() print”Elapsed time: %s”%(time.time()-start) get_responses()
Output:
http://www.jb51.net200
http://www.baidu.com200
http://www.amazon.com200
http://www.alibaba.com200
http ://www.ebay.com200
Elapsed
time:0.689890861511
Explanation:
Aware of the improvement in program execution time
We wrote a multi-threaded program to reduce the waiting time of the CPU. When we are waiting for a network request in a thread to return, the CPU can Switch to other threads to make network requests in other threads.
We expect one thread to process one url, so we pass a url when instantiating the thread class.
Thread running means executing the run() method in the class.
No matter what, we want each thread to execute run().
Create a thread for each URL and call the start() method, which tells the CPU to execute the run() method in the thread.
We want to calculate the time spent when all threads have finished executing, so we call the join() method.
join() can notify the main thread to wait for this thread to end before executing the next instruction.
We called the join() method on each thread, so we calculated the running time after all threads have completed execution.
About threads:
cpu may not execute the run() method immediately after calling start().
You cannot determine the execution order of run() among different threads.
For a single thread, it is guaranteed that the statements in the run() method are executed in order.
This is because the url in the thread will be requested first, and then the returned result will be printed.
Example 2
We will use a program to demonstrate resource competition between multi-threads and fix this problem.
from threading import Thread #define a global variable some_var=0 classIncrementThread(Thread): defrun(self): #we want to read a global variable #and then increment it globalsome_var read_value=some_var print”some_var in %s is %d”%(self.name, read_value) some_var=read_value+1 print”some_var in %s after increment is %d”%(self.name, some_var) defuse_increment_thread(): threads=[] foriinrange(50): t=IncrementThread() threads.append(t) t.start() fortinthreads: t.join() print”After 50 modifications, some_var should have become 50″ print”After 50 modifications, some_var is %d”%(some_var,) use_increment_thread()
Run this program multiple times and you will see a variety of different results.
Explanation:
There is a global variable and all threads want to modify it.
All threads should add this global variable
1
.
With 50 threads, the final value should become 50, but it does not.
Why didn’t it reach 50?
When some_var is 15, thread t1 reads some_var. At this time, the CPU gives control to another thread t2.
The some_var read by the t2 thread is also 15
Both t1 and t2 increase some_var to 16
What we expected at that time was t1
t2 two threads make some_var +
2 becomes 17
There is competition for resources here.
The same situation may also occur in other threads, so the final result may be less than 50.
Resolving resource competition
from threading import Lock, Thread lock=Lock() some_var=0 classIncrementThread(Thread): defrun(self): #we want to read a global variable #and then increment it globalsome_var lock.acquire() read_value=some_var print”some_var in %s is %d”%(self.name, read_value) some_var=read_value+1 print”some_var in %s after increment is %d”%(self.name, some_var) lock.release() defuse_increment_thread(): threads=[] foriinrange(50): t=IncrementThread() threads.append(t) t.start() fortinthreads: t.join() print”After 50 modifications, some_var should have become 50″ print”After 50 modifications, some_var is %d”%(some_var,) use_increment_thread()
Running the program again achieved the results we expected.
Explanation:
Lock
Used to prevent race conditions
If thread t1 acquires the lock before performing some operations. Other threads will not perform the same operation before t1 releases the Lock
What we want to make sure is that once thread t1 has read some_var, other threads can not read some_var until t1 has finished modifying some_var
Read like this And modifying some_var becomes a logical atomic operation.
Example 3
Let us use an example to prove that one thread cannot affect variables (non-global variables) in other threads.
time.sleep() can suspend a thread and force thread switching to occur.
from threading import Thread import time classCreateListThread(Thread): defrun(self): self.entries=[] foriinrange(10): time.sleep(1) self.entries.append(i) printself.entries defuse_create_list_thread(): foriinrange(3): t=CreateListThread() t.start() use_create_list_thread()
After running it a few times, I found that the results I was striving for were not printed out. While one thread is printing, the CPU switches to another thread, so incorrect results are produced. We need to make sure to print
self.entries is a logical atomic operation to prevent printing from being interrupted by other threads.
We used Lock(), look at the example below.
from threading import Thread, Lock import time lock=Lock() classCreateListThread(Thread): defrun(self): self.entries=[] foriinrange(10): time.sleep(1) self.entries.append(i) lock.acquire() printself.entries lock.release() defuse_create_list_thread(): foriinrange(3): t=CreateListThread() t.start() use_create_list_thread()
This time we saw the correct results. It proves that one thread cannot modify the internal variables (non-global variables) of other threads.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

The speed of mobile XML to PDF depends on the following factors: the complexity of XML structure. Mobile hardware configuration conversion method (library, algorithm) code quality optimization methods (select efficient libraries, optimize algorithms, cache data, and utilize multi-threading). Overall, there is no absolute answer and it needs to be optimized according to the specific situation.

There is no built-in sum function in C language, so it needs to be written by yourself. Sum can be achieved by traversing the array and accumulating elements: Loop version: Sum is calculated using for loop and array length. Pointer version: Use pointers to point to array elements, and efficient summing is achieved through self-increment pointers. Dynamically allocate array version: Dynamically allocate arrays and manage memory yourself, ensuring that allocated memory is freed to prevent memory leaks.

It is impossible to complete XML to PDF conversion directly on your phone with a single application. It is necessary to use cloud services, which can be achieved through two steps: 1. Convert XML to PDF in the cloud, 2. Access or download the converted PDF file on the mobile phone.

An application that converts XML directly to PDF cannot be found because they are two fundamentally different formats. XML is used to store data, while PDF is used to display documents. To complete the transformation, you can use programming languages and libraries such as Python and ReportLab to parse XML data and generate PDF documents.

XML can be converted to images by using an XSLT converter or image library. XSLT Converter: Use an XSLT processor and stylesheet to convert XML to images. Image Library: Use libraries such as PIL or ImageMagick to create images from XML data, such as drawing shapes and text.

To generate images through XML, you need to use graph libraries (such as Pillow and JFreeChart) as bridges to generate images based on metadata (size, color) in XML. The key to controlling the size of the image is to adjust the values of the <width> and <height> tags in XML. However, in practical applications, the complexity of XML structure, the fineness of graph drawing, the speed of image generation and memory consumption, and the selection of image formats all have an impact on the generated image size. Therefore, it is necessary to have a deep understanding of XML structure, proficient in the graphics library, and consider factors such as optimization algorithms and image format selection.

Use most text editors to open XML files; if you need a more intuitive tree display, you can use an XML editor, such as Oxygen XML Editor or XMLSpy; if you process XML data in a program, you need to use a programming language (such as Python) and XML libraries (such as xml.etree.ElementTree) to parse.

XML formatting tools can type code according to rules to improve readability and understanding. When selecting a tool, pay attention to customization capabilities, handling of special circumstances, performance and ease of use. Commonly used tool types include online tools, IDE plug-ins, and command-line tools.
