Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Python multithreading

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "how to use Python multithreading". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to use Python multithreading.

Python multithreading

Multithreading is similar to executing several different programs at the same time, and multithreading has the following advantages:

Threads can be used to put tasks in a program that have been occupied for a long time in the background.

The user interface can be more attractive, such as when the user clicks a button to trigger the handling of certain events, and a progress bar pops up to show the progress of the processing.

The program may run faster.

Threads are more useful in the implementation of some waiting tasks, such as user input, file reading and writing, and network data sending and receiving. In this case, we can release some precious resources such as memory footprint and so on.

There is a difference between a thread and a process during execution. Each independent process has an entrance to the program, a sequential execution sequence, and an exit to the program. However, threads cannot execute independently and must be stored in the application, which provides multiple thread execution control.

Each thread has its own set of CPU registers, called the thread's context, which reflects the status of the last time the thread ran the thread's CPU register.

The instruction pointer and the stack pointer register are the two most important registers in the thread context. The thread always runs in the context of the process. These addresses are used to indicate the memory in the process address space that owns the thread.

Threads can be preempted (interrupted).

Threads can be put on hold (also known as sleep) while other threads are running-this is the thread's concession.

Start learning Python threads

There are two ways to use threads in Python: functions or classes that wrap thread objects.

Functional: call the start_new_thread () function in the thread module to generate a new thread. The syntax is as follows:

Thread.start_new_thread (function, args [, kwargs])

Parameter description:

Function-Thread function.

Args-the parameter passed to the thread function, which must be of type tuple.

Kwargs-optional parameter.

#! / usr/bin/python#-*-coding: UTF-8-*-import threadimport time # define a function def print_time (threadName, delay): count = 0 while count < 5: time.sleep (delay) count + = 1 print "% s:% s"% (threadName, time.ctime (time.time () # create two threads try: thread.start_new_thread (print_time, ("Thread-1") 2,)) thread.start_new_thread (print_time, ("Thread-2", 4,)) except: print "Error: unable to start thread" while 1: pass

The output result of executing the above program is as follows:

Thread-1: Thu Jan 22 15:42:17 2009

Thread-1: Thu Jan 22 15:42:19 2009

Thread-2: Thu Jan 22 15:42:19 2009

Thread-1: Thu Jan 22 15:42:21 2009

Thread-2: Thu Jan 22 15:42:23 2009

Thread-1: Thu Jan 22 15:42:23 2009

Thread-1: Thu Jan 22 15:42:25 2009

Thread-2: Thu Jan 22 15:42:27 2009

Thread-2: Thu Jan 22 15:42:31 2009

Thread-2: Thu Jan 22 15:42:35 2009

The end of a thread usually depends on the natural end of the thread function; you can also call thread.exit () in the thread function, which throws a SystemExit exception to exit the thread.

Thread module

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

Other methods provided by the threading module:

Threading.currentThread (): returns the current thread variable.

Threading.enumerate (): returns a list containing the running thread. Running refers to threads after starting and ending, excluding threads before starting and terminating.

Threading.activeCount (): returns the number of running threads with the same result as len (threading.enumerate ()).

In addition to using methods, the threading module also provides the Thread class to handle threads, and the Thread class provides the following methods:

Run (): the method used to represent thread activity.

Start (): starts thread activity.

Join ([time]): wait until the thread is aborted. This blocks the calling thread until the thread's join () method is called to abort-exit normally or throw an unhandled exception-or an optional timeout occurs.

IsAlive (): returns whether the thread is active.

GetName (): returns the thread name.

SetName (): sets the thread name.

Create a thread using the Threading module

Create a thread using the Threading module, inherit directly from threading.Thread, and then override the _ _ init__ method and the run method:

#! / usr/bin/python#-*-coding: UTF-8-*-import threadingimport time exitFlag = 0 class myThread (threading.Thread): # inherit the parent class threading.Thread def _ _ init__ (self, threadID, name Counter): threading.Thread.__init__ (self) self.threadID = threadID self.name = name self.counter = counter def run (self): # write the code to be executed into the run function. The thread will run the run function print "Starting" + self.name print_time (self.name, self.counter) directly after creation. 5) print "Exiting" + self.name def print_time (threadName, delay, counter): while counter: if exitFlag: (threading.Thread). Exit () time.sleep (delay) print "% s:% s"% (threadName, time.ctime (time.time ()) counter-= 1 # create a new thread thread1 = myThread (1, "Thread-1", 1) thread2 = myThread (2 "Thread-2", 2) # start thread thread1.start () thread2.start () print "Exiting Main Thread"

The execution results of the above procedures are as follows

Starting Thread-1

Starting Thread-2

Exiting Main Thread

Thread-1: Thu Mar 21 09:10:03 2013

Thread-1: Thu Mar 21 09:10:04 2013

Thread-2: Thu Mar 21 09:10:04 2013

Thread-1: Thu Mar 21 09:10:05 2013

Thread-1: Thu Mar 21 09:10:06 2013

Thread-2: Thu Mar 21 09:10:06 2013

Thread-1: Thu Mar 21 09:10:07 2013

Exiting Thread-1

Thread-2: Thu Mar 21 09:10:08 2013

Thread-2: Thu Mar 21 09:10:10 2013

Thread-2: Thu Mar 21 09:10:12 2013

Exiting Thread-2

Thread synchronization

If multiple threads modify a certain data together, unexpected results may occur. In order to ensure the correctness of the data, multiple threads need to be synchronized.

Simple thread synchronization can be achieved using the Lock and Rlock of the Thread object, both of which have acquire and release methods, and for data that needs to be allowed to operate on only one thread at a time, you can put the operation between the acquire and release methods. As follows:

The advantage of multithreading is that you can run multiple tasks at the same time (at least it feels that way). However, when threads need to share data, the data may be out of sync.

Consider a situation where all elements in a list are 0, and thread "set" changes all elements to 1 from back to front, while thread "print" is responsible for reading the list from forward to back and printing.

So, maybe when the thread "set" starts to change, the thread "print" will print the list, and the output will be half 0 and half 1, which is the data out of sync. In order to avoid this situation, the concept of lock is introduced.

Locks have two states-locked and unlocked. Whenever a thread such as "set" wants to access shared data, it must first obtain a lock; if another thread, such as "print", has acquired the lock, then let the thread "set" pause, that is, synchronous blocking; wait until the thread "print" has finished accessing, release the lock, and then let the thread "set" continue.

After this processing, when printing the list, either all zeros or all 1s will be output, and there will be no more embarrassing situations of half zero and half one.

#! / usr/bin/python#-*-coding: UTF-8-*-import threadingimport time class myThread (threading.Thread): def _ init__ (self, threadID, name, counter): threading.Thread.__init__ (self) self.threadID = threadID self.name = name self.counter = counter def run (self): print "Starting" + self.name # get the lock Return True # if the optional timeout parameter is not filled, it will block until the lock is obtained # otherwise the timeout will return False threadLock.acquire () print_time (self.name, self.counter, 3) # release lock threadLock.release () def print_time (threadName, delay) Counter): while counter: time.sleep (delay) print "% s:% s"% (threadName, time.ctime (time.time ()) counter-= 1 threadLock = threading.Lock () threads = [] # create a new thread thread1 = myThread (1, "Thread-1", 1) thread2 = myThread (2, "Thread-2") 2) # start a new thread thread1.start () thread2.start () # add threads to the thread list threads.append (thread1) threads.append (thread2) # wait for all threads to complete for tin threads: t.join () print "Exiting Main Thread" thread priority queue (Queue)

Python's Queue module provides synchronous, thread-safe queue classes, including FIFO (first-in, first-out) queues, Queue,LIFO (last-in, first-out) queues, LifoQueue, and priority queues, PriorityQueue. These queues implement lock primitives and can be used directly in multithreading. Queues can be used to achieve synchronization between threads.

Common methods in the Queue module:

Queue.qsize () returns the size of the queue

Queue.empty () returns True if the queue is empty, and vice versa False

Queue.full () returns True if the queue is full, and vice versa False

Queue.full corresponds to maxsize size

Queue.get ([block [, timeout]]) get queue, timeout wait time

Queue.get_nowait () is equivalent to Queue.get (False)

Queue.put (item) write queue, timeout wait time

Queue.put_nowait (item) is equivalent to Queue.put (item, False)

Queue.task_done () after completing a task, the Queue.task_done () function sends a signal to the queue where the task has been completed.

Queue.join () actually means waiting for the queue to be empty before performing anything else.

#! / usr/bin/python#-*-coding: UTF-8-*-import Queueimport threadingimport time exitFlag = 0 class myThread (threading.Thread): def _ init__ (self, threadID, name, Q): threading.Thread.__init__ (self) self.threadID = threadID self.name = name self.q = q def run (self): print "Starting" + self.name process_data (self.name) Self.q) print "Exiting" + self.name def process_data (threadName, Q): while not exitFlag: queueLock.acquire () if not workQueue.empty (): data = q.get () queueLock.release () print "% s processing% s"% (threadName Data) else: queueLock.release () time.sleep (1) threadList = ["Thread-1", "Thread-2", "Thread-3"] nameList = ["One", "Two", "Three", "Four", "Five"] queueLock = threading.Lock () workQueue = Queue.Queue (10) threads = [] threadID = 1 # create a new thread for tName in threadList: thread = myThread (threadID, tName) WorkQueue) thread.start () threads.append (thread) threadID + = 1 # fill queue queueLock.acquire () for word in nameList: workQueue.put (word) queueLock.release () # wait queue empty while not workQueue.empty (): pass # notify thread that it is time to exit exitFlag = 1 # wait for all threads to complete for tin threads: t.join () print "Exiting Main Thread"

The execution results of the above procedures:

Starting Thread-1

Starting Thread-2

Starting Thread-3

Thread-1 processing One

Thread-2 processing Two

Thread-3 processing Three

Thread-1 processing Four

Thread-2 processing Five

Exiting Thread-3

Exiting Thread-1

Exiting Thread-2

Exiting Main Thread

Instance expansion:

When locking

#-*-* encoding:UTF-8-*-# author: shoushixiong# date: 2018/11/22import threadingimport timelist = [0threadId self.name = counter def run (self): print "start thread: class myThread (threading.Thread): def _ _ init__ (self,threadId,name,counter): threading.Thread.__init__ (self) self.threadId = threadId self.name = counter def run (self): print" Self.name # get the lock Return True # if the lock is obtained successfully, the optional timeout parameter will block until the lock is obtained # otherwise the timeout will return False threadLock.acquire () print_time (self.name,self.counter,list.__len__ ()) # release lock threadLock.release () def _ _ del__ (self): print self.name, "Thread ends!" Def print_time (threadName,delay,counter): while counter: time.sleep (delay) list [counter-1] + = 1 print "[% s]% s modify the d th value The modified value is:% d "% (time.ctime (time.time ()), threadName,counter, list [counter-1]) counter- = 1threadLock = threading.Lock () threads = [] # create a new thread thread1 = myThread (1," Thread-1 ", 1) thread2 = myThread (2," Thread-2 ") 2) # start a new thread thread1.start () thread2.start () # add a thread to the thread list threads.append (thread1) threads.append (thread2) # wait for all threads to finish for t in threads: t.join () print "main process ends!"

The output is as follows:

Start thread: Thread-1

Start thread: Thread-2

[Thu Nov 22 16:04:13 2018] Thread-1 modifies the 12th value to: 1

[Thu Nov 22 16:04:14 2018] Thread-1 modifies the 11th value to: 1

[Thu Nov 22 16:04:15 2018] Thread-1 modifies the 10th value to: 1

[Thu Nov 22 16:04:16 2018] Thread-1 modifies the ninth value to: 1

[Thu Nov 22 16:04:17 2018] Thread-1 modifies the eighth value to: 1

[Thu Nov 22 16:04:18 2018] Thread-1 modifies the seventh value to: 1

[Thu Nov 22 16:04:19 2018] Thread-1 modifies the sixth value to: 1

[Thu Nov 22 16:04:20 2018] Thread-1 modifies the fifth value to: 1

[Thu Nov 22 16:04:21 2018] Thread-1 modifies the fourth value to: 1

[Thu Nov 22 16:04:22 2018] Thread-1 modifies the third value to: 1

[Thu Nov 22 16:04:23 2018] Thread-1 modifies the second value to: 1

[Thu Nov 22 16:04:24 2018] Thread-1 modifies the 1st value to: 1

[Thu Nov 22 16:04:26 2018] Thread-2 modifies the 12th value to: 2

[Thu Nov 22 16:04:28 2018] Thread-2 modifies the 11th value to: 2

[Thu Nov 22 16:04:30 2018] Thread-2 modifies the 10th value to: 2

[Thu Nov 22 16:04:32 2018] Thread-2 modifies the ninth value to: 2

[Thu Nov 22 16:04:34 2018] Thread-2 modifies the eighth value to: 2

[Thu Nov 22 16:04:36 2018] Thread-2 modifies the 7th value to: 2

[Thu Nov 22 16:04:38 2018] Thread-2 modifies the sixth value to: 2

[Thu Nov 22 16:04:40 2018] Thread-2 modifies the fifth value to: 2

[Thu Nov 22 16:04:42 2018] Thread-2 modifies the fourth value to: 2

[Thu Nov 22 16:04:44 2018] Thread-2 modifies the third value to: 2

[Thu Nov 22 16:04:46 2018] Thread-2 modifies the second value to: 2

[Thu Nov 22 16:04:48 2018] Thread-2 modifies the 1st value to: 2

The main process is over!

The Thread-1 thread ends!

The Thread-2 thread ends!

When unlocked

With the same code as the example above, comment on the following two lines of code:

ThreadLock.acquire () threadLock.release ()

The output is as follows:

Start thread: Thread-1

Start thread: Thread-2

[Thu Nov 22 16:09:20 2018] Thread-1 modifies the 12th value to: 1

[Thu Nov 22 16:09:21 2018] Thread-2 modifies the 12th value to: 2

[Thu Nov 22 16:09:21 2018] Thread-1 modifies the 11th value to: 1

[Thu Nov 22 16:09:22 2018] Thread-1 modifies the 10th value to: 1

[Thu Nov 22 16:09:23 2018] Thread-1 modifies the ninth value to: 1

[Thu Nov 22 16:09:23 2018] Thread-2 modifies the 11th value to: 2

[Thu Nov 22 16:09:24 2018] Thread-1 modifies the eighth value to: 1

[Thu Nov 22 16:09:25 2018] Thread-2 modifies the 10th value to: 2

[Thu Nov 22 16:09:25 2018] Thread-1 modifies the seventh value to: 1

[Thu Nov 22 16:09:26 2018] Thread-1 modifies the sixth value to: 1

[Thu Nov 22 16:09:27 2018] Thread-2 modifies the ninth value to: 2

[Thu Nov 22 16:09:27 2018] Thread-1 modifies the fifth value to: 1

[Thu Nov 22 16:09:28 2018] Thread-1 modifies the fourth value to: 1

[Thu Nov 22 16:09:29 2018] Thread-2 modifies the eighth value to: 2

[Thu Nov 22 16:09:29 2018] Thread-1 modifies the third value to: 1

[Thu Nov 22 16:09:30 2018] Thread-1 modifies the second value to: 1

[Thu Nov 22 16:09:31 2018] Thread-2 modifies the 7th value to: 2

[Thu Nov 22 16:09:31 2018] Thread-1 modifies the 1st value to: 1

[Thu Nov 22 16:09:33 2018] Thread-2 modifies the sixth value to: 2

[Thu Nov 22 16:09:35 2018] Thread-2 modifies the fifth value to: 2

[Thu Nov 22 16:09:37 2018] Thread-2 modifies the fourth value to: 2

[Thu Nov 22 16:09:39 2018] Thread-2 modifies the third value to: 2

[Thu Nov 22 16:09:41 2018] Thread-2 modifies the second value to: 2

[Thu Nov 22 16:09:43 2018] Thread-2 modifies the 1st value to: 2

The main process is over!

The Thread-1 thread ends!

The Thread-2 thread ends!

RLock (recursive lock, reentrant lock)

What do you do when you encounter lock nesting in a thread and what happens?

Def run1 (): global count1 lock.acquire () count1 + = 1 lock.release () return count1def run2 (): global count2 lock.acquire () count2 + = 1 lock.release () return count2def runtask (): lock.acquire () R1 = run1 () print ("=" * 30) R2 = run2 () lock.release () print (R2) count1,count2 = 0Pol 0lock = threading.Lock () for index in range (50): t = threading.Thread (target=runtask,) t.start ()

This is a very simple thread lock case, the program will be stuck and stop. To address this situation, Python provides a recursive lock RLock (reentrant lock). The RLock maintains a Lock and a counter variable internally, and the counter records the number of acquire, so that the resource can be require multiple times. Resources are not available to other threads until all the acquire of one thread is release. The above code only needs to make some minor changes

At this point, I believe you have a deeper understanding of "how to use Python multithreading". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report