1 # 同一时间内执行多个任务
2 # 多任务执行的方式
3 # 并发:在一段时间内交替去执行任务
4 # 并行:指的是任务数小于等于cpu核数时,任务真的是一起执行的。
5
6 # 线程 cpu调试的基本单位 ,是程序执行的最小单位
7 # 每个进程至少都有一个线程(这个线程就是主线程)。
8 # 程序启动默认会有一个主线程
9
10 # 程序员自己创建的线程称为子线程,多线程可以完成多任务。
11
12 # 单线程
13 # import time
14 # def speak():
15 # print('老师上周没来讲课')
16 # time.sleep(2)
17 # print('结果同学们都玩去了')
18 #
19 # def dance():
20 # print('老师很伤心')
21 # time.sleep(2)
22 # print('跳个舞来挽救')
23 #
24 # if __name__ == '__main__': # 条件满足时,程序直接运行
25 # speak()
26 # dance()
27
28 # 多线程
29 # 导入模块 import threading Thread类----线程类
30 # Thread类参数:
31 # group:线程组
32 # target:执行的目标任务名
33 # args:以元组方式给执行任务来传参
34 # kwargs :以字典给执行任务传参 key = value
35 # name:线程名
36
37 # 步骤 :
38 # 1.导入模块
39 # 2.创建子线程 Thread(target=func,args=(,),……)
40 # 3.设置守护线程 setDaemon # 主线程执行完了,子线程也会跟着结束
41 # 4.启动子线程 start()
42 # 5.阻塞主线程join() t1.join()
43
44 import time
45 import threading
46
47 t1 = time.time() # 时间戳
48 def dance(name):
49 print('%s在跳鬼步舞'% name)
50 time.sleep(1)
51
52 if __name__ == '__main__':
53 for i in range(4):
54 # 创建子线程
55 t = threading.Thread(target=dance,args=('欧阳同学',)) #逗号不能省略,是元组形式
56 # 启动线程
57 t.start()
58 t2 = time.time()
59 print('执行时间是:',t2-t1)
60
61 # 多线程并发的操作
62 # 从上例可知,并发的优势,在有等待的任务执行时,能够切换到其他线程执行,提高执行效率
63
64
65 import time
66 from threading import Thread
67
68 def funa():
69 print('学习')
70 time.sleep(2)
71 print('是黎明前的黑暗')
72
73 def funb():
74 print('来这里')
75 time.sleep(2)
76 print('面包票子朋友都会有的')
77
78 if __name__ == '__main__':
79 # 创建线程
80 f1 = Thread(target=funa)
81 f2 = Thread(target=funb)
82
83 # 设置守护线程————主线程执行完了,子线程也会跟着结束
84 f1.setDaemon(True)
85 f2.setDaemon(True)
86
87 # 启动线程
88 f1.start()
89 f1.join() # f1执行完再执行主线程下面的代码(等待f1执行完再执行下面的) 我等你
90 f2.start()
91 f2.join()
92
93 # 修改名字
94 f1.setName('线程1')
95 f2.setName('线程2')
96
97 #获取名字
98 print(f1.getName())
99 print(f2.getName())
100
101 print('这是主线程,哈哈')
102
103 # 应用场景:IO密集型 多线程并发
104 # 定义一个线程类
105 # 1)继承Thread
106 # 2) 重构run方法(名称必须是run)
107 # 3)启动线程start 默认会调用 run方法
108
109 from threading import Thread
110 import time
111
112 class Ourthread(Thread): # 继承Thread类
113 # 重构run方法,规定就是用run这个名字,表示线程活动的方法
114 def run(self):
115 print('重温对象')
116 time.sleep(2)
117 print('你们还找得着北吗')
118
119 if __name__ == '__main__':
120 # 创建一个线程实例
121 t1 = Ourthread()
122 # 启动线程 start 会默认去调用run方法
123 t1.start()
124
125 # 线程之间执行是无序的,它是由cpu调试来决定的。cpu调试哪个线程,哪个线程就先执行,没有调试的线程就不能够执行。
126 import threading
127 import time
128 def task():
129 time.sleep(1)
130 print(f'当前线程:{threading.current_thread().name}\n',end='') # 获取当前线程名
131
132 if __name__ == '__main__':
133 for i in range(5):
134 t = threading.Thread(target=task)
135 t.start()
136
137 from threading import Thread
138 import time
139 list1 = [] # 全局变量
140
141 # 写数据
142 def writedata():
143 for i in range(5):
144 list1.append(i)
145 time.sleep(0.2)
146 print(f'写入的数据:{list1}\n',end='')
147
148 # 读数据
149 def readdata():
150 print(f'读取的数据:{list1}\n',end='')
151
152 if __name__ == '__main__':
153 # 创建写入数据的线程
154 wd = Thread(target=writedata)
155 # 创建读取数据的线程
156 rd = Thread(target=readdata)
157
158 # 启动线程
159 wd.start()
160 wd.join()
161 rd.start()
162 print('哈哈哈哈……')
163
164 from threading import Thread
165 a = 0
166 b = 1000000
167
168 def sum1():
169 for i in range(b):
170 global a
171 a += 1
172 print(f'第一次:{a}\n',end='')
173 # sum1()
174
175 def sum2():
176 for i in range(b):
177 global a
178 a += 1
179 print(f'第二次:{a}\n', end='')
180 # sum2()
181
182 if __name__ == '__main__':
183 # 创建线程
184 t1 = Thread(target=sum1)
185 t2 = Thread(target=sum2)
186
187 # 启动线程
188 t1.start()
189 # t1.join()
190 t2.start()
191
192 # 效果:按顺序执行 我等你执行完我(主线程)再执行
193
194 # 解决资源竞争的两种方法:1.线程同步join 2.互斥锁
195 # 互斥锁:成对出现的
196 # Lock 函数
197 # 加锁 acquire # 释放锁release
198 from threading import Thread,Lock
199 a = 0
200 b = 1000000
201 # 创建锁
202 lock = Lock()
203 def sum1():
204 lock.acquire() # 加锁
205 for i in range(b):
206 global a
207 a += 1
208 print(f'第一次:{a}\n',end='')
209 lock.release() # 解锁
210
211 def sum2():
212 lock.acquire()
213 for i in range(b):
214 global a
215 a += 1
216 print(f'第二次:{a}\n', end='')
217 lock.release()
218
219 if __name__ == '__main__':
220 # 创建线程
221 t1 = Thread(target=sum1)
222 t2 = Thread(target=sum2)
223
224 # 启动线程
225 t1.start()
226 t2.start()