程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python multithreading

編輯:Python

Threads are similar to executing multiple different programs at the same time , Multithreading has the following advantages :

  • Threads can be used to process tasks in programs that take up a long time in the background .
  • User interface can be more attractive , For example, the user clicks a button to trigger the handling of certain events , You can pop up a progress bar to show the progress of processing .
  • Program may run faster .
  • In the implementation of some waiting tasks, such as user input 、 File reading and writing, network receiving and sending data, etc , Threads are more useful . In this case, we can release some precious resources such as memory occupation and so on .

Each independent thread has an entry for the program to run 、 Exit of sequential execution sequence and program . But threads can't execute independently , Must exist in the application , Multiple thread execution control provided by the application .

Each thread has its own set CPU register , Called the context of the thread , This context reflects the CPU The state of the register .

Instruction pointer and stack pointer registers are the two most important registers in the thread context , Threads always run in the context of the process getting , These addresses are used to mark the memory in the address space of the process that owns the thread .

  • Threads can be preempted ( interrupt ).
  • When other threads are running , Threads can be suspended ( Also known as sleep ) -- This is the thread's fallback .

Threads can be divided into :

  • Kernel thread : Created and undone by the operating system kernel .
  • User threads : Threads implemented in user programs without kernel support .

Python3 The two modules commonly used in threads are :

  • _thread
  • threading( Recommended )

thread The module has been discarded . Users can use threading Module instead of . therefore , stay Python3 We can't use "thread" modular . For compatibility ,Python3 take thread Rename it to "_thread".

Begin to learn Python Threads

Python There are two ways to use threads in : Function or use class to wrap thread object .

Functional expression : call _thread Module start_new_thread() Function to generate a new thread . The grammar is as follows :

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

Parameter description :

  • function - Thread functions .
  • args - Parameters passed to the thread function , He must be a tuple type .
  • kwargs - Optional parameters .
#!/usr/bin/python3
import _thread
import time
# Define a function for the thread
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 of the above program is as follows :
Thread-1: Wed Jan 5 17:38:08 2022
Thread-2: Wed Jan 5 17:38:10 2022
Thread-1: Wed Jan 5 17:38:10 2022
Thread-1: Wed Jan 5 17:38:12 2022
Thread-2: Wed Jan 5 17:38:14 2022
Thread-1: Wed Jan 5 17:38:14 2022
Thread-1: Wed Jan 5 17:38:16 2022
Thread-2: Wed Jan 5 17:38:18 2022
Thread-2: Wed Jan 5 17:38:22 2022
Thread-2: Wed Jan 5 17:38:26 2022

You can press the ctrl-c sign out .


Thread module

Python3 Through two standard libraries _thread and threading Provides support for threads .

_thread Provides a low level of 、 The original thread and a simple lock , It's compared to threading The function of the module is limited .

threading The module contains _thread Out of all methods in the module , Other methods are also provided :

  • threading.currentThread(): Returns the current thread variable .
  • threading.enumerate(): Returns a thread containing the running thread list. Running after the thread starts 、 Before the end of the , Threads before and after startup are not included .
  • threading.activeCount(): Returns the number of running threads , And len(threading.enumerate()) It has the same result .

In addition to the method of use , The thread module also provides Thread Class to handle threads ,Thread Class provides the following methods :

  • run():  The method used to represent thread activity .
  • start(): Start thread activity .

  • join([time]):  Wait until thread aborts . This blocks the calling thread up to the thread's join() Method called to abort - Exit normally or throw unhandled exception - Or optional timeout occurs .
  • isAlive():  Returns whether the thread is active .
  • getName():  Return thread name .
  • setName():  Set the thread name .

Use threading Module creation thread

We can do this by directly from threading.Thread Inheritance creates a new subclass , After instantiation, it is called start() Method to start a new thread , That is, it calls the thread's run() Method :

example

#!/usr/bin/python3

import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, delay):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.delay = delay
    def run(self):
        print (" Start thread :" + self.name)
        print_time(self.name, self.delay, 5)
        print (" Exit thread :" + self.name)

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.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 a new thread
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print (" Exit main thread ")

The results of the above procedures are as follows ;

 Start thread :Thread-1
Start thread :Thread-2
Thread-1: Wed Jan 5 17:34:54 2022
Thread-2: Wed Jan 5 17:34:55 2022
Thread-1: Wed Jan 5 17:34:55 2022
Thread-1: Wed Jan 5 17:34:56 2022
Thread-2: Wed Jan 5 17:34:57 2022
Thread-1: Wed Jan 5 17:34:57 2022
Thread-1: Wed Jan 5 17:34:58 2022
Exit thread :Thread-1
Thread-2: Wed Jan 5 17:34:59 2022
Thread-2: Wed Jan 5 17:35:01 2022
Thread-2: Wed Jan 5 17:35:03 2022
Exit thread :Thread-2
Exit main thread 

Thread synchronization

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

Use Thread Object's Lock and Rlock It can realize simple thread synchronization , Both of these objects have acquire Methods and release Method , For data that requires only one thread at a time , It can be operated in acquire and release Between methods . as follows :

The advantage of multithreading is that it can run multiple tasks at the same time ( At least it feels like this ). But when threads need to share data , There may be data out of sync .

Consider a situation like this : All the elements in a list are 0, Threads "set" Change all elements from back to front to 1, And threads "print" Responsible for reading the list from front to back and printing .

that , Maybe threads "set" At the beginning of the change , Threads "print" So I'm going to print the list , The output is half 0 Half 1, This is the data out of sync . To avoid that , The concept of lock is introduced .

There are two states of lock —— Locked and unlocked . Every time a thread such as "set" To access shared data , Lock must be obtained first ; If there are other threads such as "print" Get locked , So let the thread "set" Pause , That's synchronous blocking ; Wait until the thread "print" Access to complete , After releasing the lock , Let the thread "set" continue .

After such treatment , When printing a list, you can either print it all 0, Or output it all 1, No more half 0 Half 1 The embarrassment of .

example

#!/usr/bin/python3

import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, delay):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.delay = delay
    def run(self):
        print (" Open thread : " + self.name)
        # Get the lock , For thread synchronization
        threadLock.acquire()
        print_time(self.name, self.delay, 3)
        # Release the lock , Start the next thread
        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 thread to thread list
threads.append(thread1)
threads.append(thread2)

# Wait for all threads to finish
for t in threads:
    t.join()
print (" Exit main thread ")

Execute the above procedure , The output is :

 Open thread : Thread-1
Open thread : Thread-2
Thread-1: Wed Jan 5 17:36:50 2022
Thread-1: Wed Jan 5 17:36:51 2022
Thread-1: Wed Jan 5 17:36:52 2022
Thread-2: Wed Jan 5 17:36:54 2022
Thread-2: Wed Jan 5 17:36:56 2022
Thread-2: Wed Jan 5 17:36:58 2022
Exit main thread 

Thread priority queue ( Queue)

Python Of Queue Synchronous... Is provided in the module 、 Thread safe queue class , Include FIFO( First in, first out ) queue Queue,LIFO( After the first out ) queue LifoQueue, And priority queues PriorityQueue.

These queues all implement lock primitives , Can be used directly in multithreading , You can use queues to synchronize threads .

Queue Common methods in modules :

  • Queue.qsize() Returns the size of the queue
  • Queue.empty() If the queue is empty , return True, conversely False
  • Queue.full() If the queue is full , return True, conversely False
  • Queue.full And maxsize Size correspondence
  • Queue.get([block[, timeout]]) Get the queue ,timeout Waiting time
  • Queue.get_nowait() Quite a Queue.get(False)
  • Queue.put(item) Written to the queue ,timeout Waiting time
  • Queue.put_nowait(item) Quite a Queue.put(item, False)
  • Queue.task_done() After finishing a job ,Queue.task_done() Function sends a signal to the queue that the task has completed
  • Queue.join() It essentially means waiting until the queue is empty , Do something else

example

#!/usr/bin/python3

import queue
import threading
import 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 (" Open thread :" + self.name)
        process_data(self.name, self.q)
        print (" Exit thread :" + 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 the queue
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# Wait for the queue to clear
while not workQueue.empty():
    pass

# Notify the thread that it's time to exit
exitFlag = 1

# Wait for all threads to finish
for t in threads:
    t.join()
print (" Exit main thread ")

The results of the above procedures :

 Open thread :Thread-1
Open thread :Thread-2
Open thread :Thread-3
Thread-3 processing One
Thread-1 processing Two
Thread-2 processing Three
Thread-3 processing Four
Thread-1 processing Five
Exit thread :Thread-3
Exit thread :Thread-2
Exit thread :Thread-1
Exit main thread 

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved