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 :
Parameter description :
example :
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
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 :
In addition to the method of use , The thread module also provides Thread Class to handle threads ,Thread Class provides the following methods :
It can be done 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 :
import threading
import time
exitFlag = 0
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 (" Start thread :" + self.name)
print_time(self.name, self.counter, 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 ")
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 :
Be careful :
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, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print (" Open thread : " + self.name)
# Get the lock , For thread synchronization
threadLock.acquire()
print_time(self.name, self.counter, 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 ")
1.python3 The queue module in is queue, No Queue
2. Generally, synchronization is involved , Multithreading and the like use queue modules
3. Defined queue.Queue class , And inherit it queue.LifoQueue class and queue.PriorityQueue class and queue.SimpleQueue class
4. Corresponding to the queue class (FIFO fifo ),LIFO LIFO queue class , Priority queue , Borderless FIFO Simple queue class
5. There are two other exceptions : Team full and team empty
''' No one answers the problems encountered in learning ? Xiaobian created a Python Exchange of learning QQ Group :857662006 Looking for small partners who share the same aspiration , Help each other , There are also good video tutorials and PDF e-book ! '''
import queue
# Create a basic queue
#queue.Queue(maxsize=0) Create a queue object ( Queue capacity ), if maxsize Less than or equal to 0, There is no limit to the size of the queue
Q=queue.Queue(10)
print(Q)
print(type(Q))
#1. The basic method
print(Q.queue)# View all elements in the queue
print(Q.qsize())# Returns the size of the queue
print(Q.empty())# Judge team empty
print(Q.full())# Judge that the team is full
#2. Get the queue ,0--5
#Queue.put(item,block = True,timeout = None ) Put the object in the queue , Blocking call (block=False Throw exceptions ), No waiting time
for i in range(5):
Q.put(i)
# Queue.put_nowait(item) amount to put(item, False).
#3. Read the queue ,0--5
#Queue.get(block=True, timeout=None) Read an element of the queue , Blocking call , No waiting time
while not Q.empty():
print(Q.get())
# Queue.get_nowait() amount to get(False). Take the data , If there's no data queue.Empty abnormal
#4. The other two involve waiting for queued tasks
# Queue.task_done() After finishing a job , Send a signal to the queue where the task has been completed
# Queue.join() Block until all items in the queue are fetched and processed . That is, wait until the queue is empty before performing other operations
1.LifoQueue: LIFO Last in, first out
2.PriorityQueue: Priority queue , If the data elements are not comparable , You can wrap the data in a class that ignores data items , Only compare priority numbers
3.SimpleQueue: Simple queue , No function to track tasks
Queue Common methods in modules :
example :
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 ")