This article brings you relevant knowledge about Python, which mainly introduces the relevant content about multi-threading. Multiple threads can run in the same program, and each thread completes Let’s take a look at the different tasks below. I hope it will be helpful to everyone.
【Related recommendations: Python3 video tutorial】
Thread is the basic unit for CPU to allocate resources. When a program starts running, the program becomes a process, and a process is equivalent to one or more threads. When there is no multi-thread programming, a process is equivalent to a main thread; when there is multi-thread programming, a process contains multiple threads (including the main thread). Large program development can be achieved using threads.
Multiple threads can run in the same program, and each thread completes different tasks.
Multi-threaded background service program can handle multiple tasks at the same time without blocking.
The characteristic of multi-threaded programming is that it can improve program execution efficiency and processing speed. Python programs can run multiple relatively independent threads in parallel at the same time.
Python supports two ways to create multi-threads:
~Created through threading.Thread ().
~By inheriting the threading.Thread class.
Grammar form:
thread.Thread(group=Nore,targt=None,args=(),kwargs={},*,daemon=None)
Parameter explanation:
~group: must be None, related to ThreadGroup class, generally not used.
~target: The object called by the thread is the target function.
~name: Give this name to the thread. The default is Tread-x, x is the serial number, starting from 1, and the name of the first thread created is Tread-1.
~args: Pass keyword arguments and dictionary to the target function.
~daemon: Used to set whether the thread exits when the main thread exits.
Example:
import threading def test (x,y): for i in range(x,y): print(i) thread1 = threading.Thread(name='t1',target= test,args=(1,10)) thread2 = threading.Thread(name='t2',target= test,args=(11,20)) thread1.start() #启动线程1 thread2.start() #启动线程2
Output:
1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19
Explanation: The two programs will run concurrently, so the results may not be sequential 1~10 every time. This is based on The CPU allocates time segments to the two threads. You can see that the results are different every time.
threading.Thread is a class and you can inherit it.
Example:
import threading class mythread(threading.Thread): def run(self): for i in range(1,10): print(i) thread1 = mythread(); thread2 = mythread(); thread1.start() thread2.start()
Output:
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
Explanation: Customize a class to inherit threading.Thread, and then override the run method of the parent class. When the thread starts (execute start ()) will automatically execute this method.
In python, the main thread is the first thread to start.
~Parent thread: If a thread B is started in the starting thread A, A is the parent thread of B.
~Sub-thread: B is the sub-thread of A.
When creating a thread, there is a damon attribute, which is used to determine the main thread. When the daemon is set to False, the thread will not exit when the main thread exits, and the main thread will wait for the child thread to finish executing;. When the daemon is set to True, the thread will exit when the main thread exits, and other child threads will be forced to exit when the main thread ends.
Note when using daemon:
~The daemon attribute must be set before start(), otherwise a RuntimeError exception will be raised
~Each thread has a daemon attribute that can be set explicitly You can also not set it. If not set, the default value is None
~If the sub-sub-thread does not set the daemon attribute, take the daemon of the current thread to set it. The child thread inherits the daemon value of the child thread, which has the same effect as setting None.
~All threads created from the main thread do not set the daemon attribute, and the default is daemon=False.
Example:
import time import threading def test(): time.sleep(10) for i in range(10): print(i) thread1 = threading.Thread(target=test,daemon=False) thread1.start() print('主线程完成了')
Output:
主线程完成了 0 1 2 3 4 5 6 7 8 9
Explanation: When the main thread finishes running and outputs, wait for a while and then output 0~9. If daemon=False is changed to daemon=True, the for i in range(10) statement will not be run.
When a thread calls the join method of another thread, the caller is blocked until the calling thread is terminated.
Grammar form:
join(timeout-=None)
The timeout parameter specifies how long the caller waits. If it is not set, it will wait for the called thread to end and the called thread to end. Among them, a thread can be called multiple times by join.
Example:
import time import threading def test(): time.sleep(5) for i in range(10): print(i) thread1=threading.Thread(target=test) thread1.start() thread1.join() print('主线程完成了')
Output:
0 1 2 3 4 5 6 7 8 9 主线程完成了
Explanation: Add thread1.join() after thread1.start() to add the join method. When outputting, the main thread will Wait for 0~9 to be output before executing your own print output.
~run(): Method used to indicate thread activity
~start(): Start the thread
~join(): Wait until the thread terminates
~isAlive(): Return whether the thread is active
~getName(): Return the thread name
~setName(): Set the thread name
Example:
from threading import Thread, Event import time def countdown(n, started_evt): print('正在运行') started_evt.set() while n > 0: print('时间', n) n -= 1 time.sleep(2) started_evt = Event() print('开始倒计时') t = Thread(target=countdown, args=(10, started_evt)) t.start() started_evt.wait() print('倒计时运行')
Output:
开始倒计时 正在运行 时间 10 倒计时运行 时间 9 时间 8 时间 7 时间 6 时间 5 时间 4 时间 3 时间 2 时间 1
Alive,顾名思义,它表示线程当前是否为可用状态,如果线程已经启动,并且当前没有任何异常的话,则返回true,否则为false
Thread.isAlive() :顾名思义,是表示当前线程时候为可用状态,即是否已经在启动,并且在运行的状态;
异步模式的情况下,同时有一个线程在修改共享数据,另一个线程在读取共享数据,当修改的共享数据的线程没有处理完毕,读取数据的线程肯定会得到错误的结果。如果采用多线程的同步控制机制,当处理共享数据的线程完成处理数据之后,读取线程就读取数据。
python的锁就解决这一问题,锁住线程,只允许一个线程操作,其他线程排队等待,待当前线程操作完毕后,再按顺序一个一个来运行。
python的threading模块提供了RLock锁解决方法。在某一时间只能让一个线程操作的语句放到RLock的acquire方法和release方法之间,即acquire相当于给RLack上锁,而release相当于解锁。
示例:
import threading class mythread(threading.Thread): def run(self): global x #声明一个全局变量 lock.acquire() #上锁 x +=10 print('%s:%d'%(self.name,x)) lock.release() #解锁 x = 0 #设置全局变量初始值 lock = threading.RLock() #创建可重入锁 list1 = [] for i in range(5): list1.append(mythread()) #创建五个线程,放到同一列表中 for i in list1: i.start() #开启列表线程
输出:
Thread-1:10 Thread-2:20 Thread-3:30 Thread-4:40 Thread-5:50
解释:
条件锁常用的方法:
~acquire([timeout]):调用关联锁的方法
~release():解锁
~wait():使线程进入 Condition 的等待池等待通知并释放解锁。使用前线程必须已获得锁定,否则将抛出异常。
~notify():从等待池挑选一个线程并通知,收到通知的线程将自动调用 acquire() 尝试获得,其他线程仍然在等待池中等待通知,直到该线程收到通知 调用该方法,否则将会抛出异常。
~notify ALL():跟notify() 一样,但这个方法对应的是所有的线程。
示例:
题目:有几个生产车间生产,几个消费者购买,当生产达到一定数量时,停止生产。
import threading import time condtion = threading.Condition() sheep = ['1件产品','1件产品','1件产品','1件产品','1件产品'] class Producer(threading.Thread): def __init__(self, name): super().__init__(name=name) pass def run(self): global condtion, sheep while True: time.sleep(0.1) condtion.acquire() if len(sheep) < 10: print(self.name + "生产了1件产品") sheep.append('1件产品') condtion.notifyAll() pass else: print("仓库满了,停止生产!") condtion.wait() pass condtion.release() pass pass class Customer(threading.Thread): def __init__(self, name): super().__init__(name=name) pass def run(self): global condtion, sheep while True: time.sleep(0.1) condtion.acquire() if len(sheep) > 0: meat = sheep.pop() print(self.name + "购买了" + meat + "还剩多少" + str(len(sheep)) + "件") condtion.notifyAll() pass else: print("买光了,等待") condtion.wait() pass condtion.release() pass pass if __name__ == "__main__": p1 = Producer("1号生产车间") p2 = Producer("2号生产车间") p3 = Producer("3号生产车间") p4 = Producer("4号生产车间") p5 = Producer("5号生产车间") p6 = Producer("6号生产车间") p1.start() p2.start() p4.start() p5.start() p6.start() c1 = Customer('小王') c2 = Customer('小李') c3 = Customer('小贾') c4 = Customer('小沈') c5 = Customer('小刘') c1.start() c2.start() c3.start() c4.start() c5.start()
【相关推荐:Python3视频教程 】
The above is the detailed content of Multithreading in python (summary). For more information, please follow other related articles on the PHP Chinese website!