0、承上
什么是线程?
CPU调度的最小单位。
线程是进程的必要组成单位。
主线程:
程序开始运行的时候,就产生了一个主线进程来运行这个程序。
子线程:
是由主线程开启的其他线程。
· 各线程之间的工作关系
异步的
数据共享的
GIL锁:Cpython解释器中有一把锁,锁的是线程。
线程是CPU调度的最小单位
1、线程的开启
线程不能在外界干扰下结束,而是等待程序执行完毕才结束的,主线程要等待子线程的结束而结束
1 from threading import Thread, currentThread 2 3 def t_func(): 4 global n 5 n -= 1 6 print(currentThread()) 7 8 if __name__ == '__main__': 9 n = 100 10 t_lst = [] 11 for i in range(100): 12 t = Thread(target=t_func) 13 t.start() 14 t_lst.append(t) 15 print(t.ident, t.name, t.is_alive()) 16 for t in t_lst: 17 t.join() 18 print(n)
D:\Python36\python.exe E:/Python/草稿纸0.py <Thread(Thread-1, started 20124)> 20124 Thread-1 True <Thread(Thread-2, started 20128)> 20128 Thread-2 True <Thread(Thread-3, started 20132)> 20132 Thread-3 True <Thread(Thread-4, started 20136)> 20136 Thread-4 True <Thread(Thread-5, started 20140)> 20140 Thread-5 True <Thread(Thread-6, started 20144)> 20144 Thread-6 True <Thread(Thread-7, started 20148)> 20148 Thread-7 True <Thread(Thread-8, started 20152)> 20152 Thread-8 True <Thread(Thread-9, started 20156)> 20156 Thread-9 True <Thread(Thread-10, started 20160)> 20160 Thread-10 True <Thread(Thread-11, started 20164)> 20164 Thread-11 True <Thread(Thread-12, started 20168)> 20168 Thread-12 True <Thread(Thread-13, started 20172)> 20172 Thread-13 True <Thread(Thread-14, started 20176)> 20176 Thread-14 True <Thread(Thread-15, started 20180)> 20180 Thread-15 True <Thread(Thread-16, started 20184)> 20184 Thread-16 True <Thread(Thread-17, started 20188)> 20188 Thread-17 True <Thread(Thread-18, started 20192)> 20192 Thread-18 True <Thread(Thread-19, started 20196)> 20196 Thread-19 True <Thread(Thread-20, started 20200)> 20200 Thread-20 True <Thread(Thread-21, started 20204)> 20204 Thread-21 True <Thread(Thread-22, started 20208)> 20208 Thread-22 True <Thread(Thread-23, started 20212)> 20212 Thread-23 True <Thread(Thread-24, started 20216)> 20216 Thread-24 True <Thread(Thread-25, started 20220)> 20220 Thread-25 True <Thread(Thread-26, started 20224)> 20224 Thread-26 True <Thread(Thread-27, started 20228)> 20228 Thread-27 True <Thread(Thread-28, started 20232)> 20232 Thread-28 True <Thread(Thread-29, started 20236)> 20236 Thread-29 True <Thread(Thread-30, started 20240)> 20240 Thread-30 True <Thread(Thread-31, started 20244)> 20244 Thread-31 True <Thread(Thread-32, started 20248)> 20248 Thread-32 True <Thread(Thread-33, started 20252)> 20252 Thread-33 False <Thread(Thread-34, started 20256)> 20256 Thread-34 True <Thread(Thread-35, started 20260)> 20260 Thread-35 True <Thread(Thread-36, started 20264)> 20264 Thread-36 False <Thread(Thread-37, started 20268)> 20268 Thread-37 True <Thread(Thread-38, started 20272)> 20272 Thread-38 True <Thread(Thread-39, started 20276)> 20276 Thread-39 False <Thread(Thread-40, started 20280)> 20280 Thread-40 True <Thread(Thread-41, started 20284)> 20284 Thread-41 True <Thread(Thread-42, started 20288)> 20288 Thread-42 True <Thread(Thread-43, started 20292)> 20292 Thread-43 False <Thread(Thread-44, started 20296)> 20296 Thread-44 True <Thread(Thread-45, started 20300)> 20300 Thread-45 False <Thread(Thread-46, started 20304)> 20304 Thread-46 True <Thread(Thread-47, started 20308)> 20308 Thread-47 True <Thread(Thread-48, started 20312)> 20312 Thread-48 True <Thread(Thread-49, started 20316)> 20316 Thread-49 False <Thread(Thread-50, started 20320)> 20320 Thread-50 False <Thread(Thread-51, started 20324)> 20324 Thread-51 True <Thread(Thread-52, started 20328)> 20328 Thread-52 True <Thread(Thread-53, started 20332)> 20332 Thread-53 True <Thread(Thread-54, started 20336)> 20336 Thread-54 True <Thread(Thread-55, started 20340)> 20340 Thread-55 True <Thread(Thread-56, started 20344)> 20344 Thread-56 True <Thread(Thread-57, started 20348)> 20348 Thread-57 True <Thread(Thread-58, started 20352)> 20352 Thread-58 True <Thread(Thread-59, started 20356)> 20356 Thread-59 True <Thread(Thread-60, started 20360)> 20360 Thread-60 True <Thread(Thread-61, started 20364)> 20364 Thread-61 True <Thread(Thread-62, started 20368)> 20368 Thread-62 False <Thread(Thread-63, started 20372)> 20372 Thread-63 True <Thread(Thread-64, started 20376)> 20376 Thread-64 True <Thread(Thread-65, started 20380)> 20380 Thread-65 True <Thread(Thread-66, started 20384)> 20384 Thread-66 True <Thread(Thread-67, started 20388)> 20388 Thread-67 True <Thread(Thread-68, started 20392)> 20392 Thread-68 False <Thread(Thread-69, started 20396)> 20396 Thread-69 True <Thread(Thread-70, started 20400)> 20400 Thread-70 True <Thread(Thread-71, started 20404)> 20404 Thread-71 True <Thread(Thread-72, started 20408)> 20408 Thread-72 False <Thread(Thread-73, started 20412)> 20412 Thread-73 True <Thread(Thread-74, started 20416)> 20416 Thread-74 True <Thread(Thread-75, started 20420)> 20420 Thread-75 True <Thread(Thread-76, started 20424)> 20424 Thread-76 True <Thread(Thread-77, started 20428)> 20428 Thread-77 False <Thread(Thread-78, started 20432)> 20432 Thread-78 True <Thread(Thread-79, started 20436)> 20436 Thread-79 True <Thread(Thread-80, started 20440)> 20440 Thread-80 True <Thread(Thread-81, started 20444)> 20444 Thread-81 True <Thread(Thread-82, started 20448)> 20448 Thread-82 True <Thread(Thread-83, started 20452)> 20452 Thread-83 True <Thread(Thread-84, started 20456)> 20456 Thread-84 True <Thread(Thread-85, started 20460)> 20460 Thread-85 True <Thread(Thread-86, started 20464)> 20464 Thread-86 False <Thread(Thread-87, started 20468)> 20468 Thread-87 True <Thread(Thread-88, started 20472)> 20472 Thread-88 True <Thread(Thread-89, started 20476)> 20476 Thread-89 True <Thread(Thread-90, started 19584)> 19584 Thread-90 True <Thread(Thread-91, started 19588)> 19588 Thread-91 True <Thread(Thread-92, started 6800)> 6800 Thread-92 True <Thread(Thread-93, started 19568)> 19568 Thread-93 True <Thread(Thread-94, started 18904)> 18904 Thread-94 True <Thread(Thread-95, started 19604)> 19604 Thread-95 True <Thread(Thread-96, started 19608)> 19608 Thread-96 True <Thread(Thread-97, started 19612)> 19612 Thread-97 True <Thread(Thread-98, started 19620)> 19620 Thread-98 True <Thread(Thread-99, started 19616)> 19616 Thread-99 True <Thread(Thread-100, started 19624)> 19624 Thread-100 True 0 Process finished with exit code 0
2、守护线程
主进程守护 会等待主进程的代码执行结束而结束。
import time from multiprocessing import Process def func1(): time.sleep(3) print('in func1') def func2(): while True: time.sleep(0.5) print('in func2') if __name__ == '__main__': Process(target=func1).start() t = Process(target=func2) t.daemon = True t.start() print('主进程')
D:\Python36\python.exe E:/Python/草稿纸0.py 主进程 in func1 Process finished with exit code 0
主线程守护 会等待主线程执行完毕才结束,主线程会等待所有子进程结束而结束。
1 import time 2 from threading import Thread 3 4 def func1(): 5 time.sleep(3) 6 print('in func1') 7 8 def func2(): 9 while True: 10 time.sleep(0.5) 11 print('in func2') 12 13 if __name__ == '__main__': 14 Thread(target=func1).start() 15 t = Thread(target=func2) 16 t.setDaemon(True) 17 t.start() 18 print('主线程')
D:\Python36\python.exe E:/Python/草稿纸0.py 主线程 in func2 in func2 in func2 in func2 in func2 in func2 in func1 Process finished with exit code 0
3、锁
1 from threading import Thread 2 3 def t_func(): 4 global n 5 n -= 1 6 7 if __name__ == '__main__': 8 n = 200000 9 t_lst = [] 10 for i in range(200000): 11 t = Thread(target=t_func) 12 t.start() 13 t_lst.append(t) 14 for t in t_lst: 15 t.join() 16 print(n)
D:\Python36\python.exe E:/Python/草稿纸0.py
0
Process finished with exit code 0
1 import threading 2 3 balance = 0 4 def change_it(n): 5 global balance 6 balance = balance + n 7 balance = balance - n 8 9 def run_thread(n, lock): 10 for i in range(150000): 11 change_it(n) 12 13 lock = threading.Lock() 14 t1 = threading.Thread(target=run_thread, args=(5, lock)) 15 t2 = threading.Thread(target=run_thread, args=(5, lock)) 16 t1.start() 17 t2.start() 18 t1.join() 19 t2.join() 20 print(balance)
D:\Python36\python.exe E:/Python/草稿纸0.py -5 Process finished with exit code 0
D:\Python36\python.exe E:/Python/草稿纸0.py
0
Process finished with exit code 0
1 import threading 2 3 balance = 0 4 def change_it(n): 5 global balance 6 balance = balance + n 7 balance = balance - n 8 9 def run_thread(n, lock): 10 for i in range(150000): 11 with lock: 12 change_it(n) 13 14 lock = threading.Lock() 15 t1 = threading.Thread(target=run_thread, args=(5, lock)) 16 t2 = threading.Thread(target=run_thread, args=(5, lock)) 17 t1.start() 18 t2.start() 19 t1.join() 20 t2.join() 21 print(balance)
D:\Python36\python.exe E:/Python/草稿纸0.py
0
Process finished with exit code 0
4、死锁
互斥锁和递归锁的区别:
互斥锁在同一个线程中连续acquire一次以上就会死锁
递归锁在同一个线程中可以连续的acquire多次而不会发生死锁
普遍:递归锁可以替代互斥锁来解决死锁现象
实际上: 递归锁的解决死锁实际上是牺牲了时间和空间的
死锁本质上来讲是一种逻辑上的错误
递归锁没有从本质上解决死锁的问题
互斥锁
1 from threading import Lock 2 lock = Lock() 3 lock.acquire() 4 print(123) 5 lock.release()
D:\Python36\python.exe E:/Python/草稿纸0.py 123 Process finished with exit code 0
递归锁
1 from threading import RLock 2 3 lock = RLock() 4 lock.acquire() 5 lock.acquire() 6 print(123) 7 lock.release()
D:\Python36\python.exe E:/Python/草稿纸0.py 123 Process finished with exit code 0
吃面问题(死锁)
1 from threading import Thread, Lock 2 3 def eat1(name, fork_lock, noodle_lock): 4 fork_lock.acquire() 5 print(f'{name}拿到叉子了') 6 noodle_lock.acquire() 7 print(f'{name}拿到面条了') 8 print(f'{name}吃面') 9 noodle_lock.release() 10 fork_lock.release() 11 12 def eat2(name, fork_lock, noodke_lock): 13 noodke_lock.acquire() 14 print(f'{name}拿到面条了') 15 fork_lock.acquire() 16 print(f'{name}拿到叉子了') 17 print(f'{name}吃面') 18 fork_lock.release() 19 noodke_lock.release() 20 21 fork_lock = Lock() 22 noodle_lock = Lock() 23 Thread(target=eat1, args=('alex', fork_lock, noodle_lock)).start() 24 Thread(target=eat2, args=('wusir', fork_lock, noodle_lock)).start() 25 Thread(target=eat1, args=('yuan', fork_lock, noodle_lock)).start() 26 Thread(target=eat2, args=('jin', fork_lock, noodle_lock)).start()
D:\Python36\python.exe E:/Python/草稿纸0.py
alex拿到叉子了
alex拿到面条了
alex吃面
wusir拿到面条了
wusir拿到叉子了
wusir吃面
yuan拿到叉子了
yuan拿到面条了
yuan吃面
jin拿到面条了
jin拿到叉子了
jin吃面
Process finished with exit code 0
递归锁解决死锁现象
1 from threading import Thread, RLock 2 3 def eat1(name, fork_lock, noodle_lock): 4 fork_lock.acquire() 5 print(f'{name}拿到叉子了') 6 noodle_lock.acquire() 7 print(f'{name}拿到面了') 8 print(f'{name}吃面') 9 noodle_lock.release() 10 fork_lock.release() 11 12 def eat2(name, fork_lock, noodle_lock): 13 noodle_lock.acquire() 14 print(f'{name}拿到面条了') 15 fork_lock.acquire() 16 print(f'{name}拿到叉子了') 17 print(f'{name}吃面') 18 fork_lock.release() 19 noodle_lock.release() 20 21 noodle_lock = fork_lock = RLock() 22 Thread(target=eat1, args=('alex', fork_lock, noodle_lock)).start() 23 Thread(target=eat2, args=('wusir', fork_lock, noodle_lock)).start() 24 Thread(target=eat1, args=('yuan', fork_lock, noodle_lock)).start() 25 Thread(target=eat2, args=('jin', fork_lock, noodle_lock)).start()
D:\Python36\python.exe E:/Python/草稿纸0.py
alex拿到叉子了
alex拿到面了
alex吃面
wusir拿到面条了
wusir拿到叉子了
wusir吃面
yuan拿到叉子了
yuan拿到面了
yuan吃面
jin拿到面条了
jin拿到叉子了
jin吃面
Process finished with exit code 0
1 import time 2 from threading import Thread, Lock 3 4 def eat1(name, lock): 5 lock.acquire() 6 print(f'{name}拿到叉子了') 7 print(f'{name}拿到面条了') 8 print(f'{name}吃面') 9 lock.release() 10 11 def eat2(name, lock): 12 lock.acquire() 13 print(f'{name}拿到面条了') 14 time.sleep(1) 15 print(f'{name}拿到叉子了') 16 print(f'{name}吃面') 17 lock.release() 18 19 noodle_fork_lock = Lock() 20 Thread(target=eat1, args=('alex', noodle_fork_lock)).start() 21 Thread(target=eat2, args=('wusir', noodle_fork_lock)).start() 22 Thread(target=eat1, args=('yuan', noodle_fork_lock)).start() 23 Thread(target=eat2, args=('jin', noodle_fork_lock)).start()
D:\Python36\python.exe E:/Python/草稿纸0.py
alex拿到叉子了
alex拿到面条了
alex吃面
wusir拿到面条了
wusir拿到叉子了
wusir吃面
yuan拿到叉子了
yuan拿到面条了
yuan吃面
jin拿到面条了
jin拿到叉子了
jin吃面
Process finished with exit code 0
5、事件
未完待续。。。
6、定时器
未完待续。。。
7、条件
未完待续。。。
8、队列
未完待续。。。
9、池
未完待续。。。