0、承上

  什么是线程?

    CPU调度的最小单位。

    线程是进程的必要组成单位。

  主线程:

    程序开始运行的时候,就产生了一个主线进程来运行这个程序。

  子线程:

    是由主线程开启的其他线程。

·  各线程之间的工作关系

    异步的

    数据共享的

  GIL锁:Cpython解释器中有一把锁,锁的是线程。

  线程是CPU调度的最小单位

1、线程的开启

  线程不能在外界干扰下结束,而是等待程序执行完毕才结束的,主线程要等待子线程的结束而结束

 from threading import Thread, currentThread

 def t_func():
global n
n -= 1
print(currentThread()) if __name__ == '__main__':
n = 100
t_lst = []
for i in range(100):
t = Thread(target=t_func)
t.start()
t_lst.append(t)
print(t.ident, t.name, t.is_alive())
for t in t_lst:
t.join()
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

结果

  主线程守护  会等待主线程执行完毕才结束,主线程会等待所有子进程结束而结束。

 import time
from threading import Thread def func1():
time.sleep(3)
print('in func1') def func2():
while True:
time.sleep(0.5)
print('in func2') if __name__ == '__main__':
Thread(target=func1).start()
t = Thread(target=func2)
t.setDaemon(True)
t.start()
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、锁

 from threading import Thread

 def t_func():
global n
n -= 1 if __name__ == '__main__':
n = 200000
t_lst = []
for i in range(200000):
t = Thread(target=t_func)
t.start()
t_lst.append(t)
for t in t_lst:
t.join()
print(n)

锁1

D:\Python36\python.exe E:/Python/草稿纸0.py
0 Process finished with exit code 0

结果

 import threading

 balance = 0
def change_it(n):
global balance
balance = balance + n
balance = balance - n def run_thread(n, lock):
for i in range(150000):
change_it(n) lock = threading.Lock()
t1 = threading.Thread(target=run_thread, args=(5, lock))
t2 = threading.Thread(target=run_thread, args=(5, lock))
t1.start()
t2.start()
t1.join()
t2.join()
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

结果(正常)

 import threading

 balance = 0
def change_it(n):
global balance
balance = balance + n
balance = balance - n def run_thread(n, lock):
for i in range(150000):
with lock:
change_it(n) lock = threading.Lock()
t1 = threading.Thread(target=run_thread, args=(5, lock))
t2 = threading.Thread(target=run_thread, args=(5, lock))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)

线程加锁

D:\Python36\python.exe E:/Python/草稿纸0.py
0 Process finished with exit code 0

结果

4、死锁

  互斥锁和递归锁的区别:

    互斥锁在同一个线程中连续acquire一次以上就会死锁

    递归锁在同一个线程中可以连续的acquire多次而不会发生死锁

  普遍:递归锁可以替代互斥锁来解决死锁现象

  实际上:  递归锁的解决死锁实际上是牺牲了时间和空间的

    死锁本质上来讲是一种逻辑上的错误

    递归锁没有从本质上解决死锁的问题

  互斥锁

 from threading import Lock
lock = Lock()
lock.acquire()
print(123)
lock.release()

互斥锁

D:\Python36\python.exe E:/Python/草稿纸0.py
123 Process finished with exit code 0

结果

  递归锁

 from threading import RLock

 lock = RLock()
lock.acquire()
lock.acquire()
print(123)
lock.release()

递归锁

D:\Python36\python.exe E:/Python/草稿纸0.py
123 Process finished with exit code 0

结果

  吃面问题(死锁)

 from threading import Thread, Lock

 def eat1(name, fork_lock, noodle_lock):
fork_lock.acquire()
print(f'{name}拿到叉子了')
noodle_lock.acquire()
print(f'{name}拿到面条了')
print(f'{name}吃面')
noodle_lock.release()
fork_lock.release() def eat2(name, fork_lock, noodke_lock):
noodke_lock.acquire()
print(f'{name}拿到面条了')
fork_lock.acquire()
print(f'{name}拿到叉子了')
print(f'{name}吃面')
fork_lock.release()
noodke_lock.release() fork_lock = Lock()
noodle_lock = Lock()
Thread(target=eat1, args=('alex', fork_lock, noodle_lock)).start()
Thread(target=eat2, args=('wusir', fork_lock, noodle_lock)).start()
Thread(target=eat1, args=('yuan', fork_lock, noodle_lock)).start()
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

结果

  递归锁解决死锁现象

 from threading import Thread, RLock

 def eat1(name, fork_lock, noodle_lock):
fork_lock.acquire()
print(f'{name}拿到叉子了')
noodle_lock.acquire()
print(f'{name}拿到面了')
print(f'{name}吃面')
noodle_lock.release()
fork_lock.release() def eat2(name, fork_lock, noodle_lock):
noodle_lock.acquire()
print(f'{name}拿到面条了')
fork_lock.acquire()
print(f'{name}拿到叉子了')
print(f'{name}吃面')
fork_lock.release()
noodle_lock.release() noodle_lock = fork_lock = RLock()
Thread(target=eat1, args=('alex', fork_lock, noodle_lock)).start()
Thread(target=eat2, args=('wusir', fork_lock, noodle_lock)).start()
Thread(target=eat1, args=('yuan', fork_lock, noodle_lock)).start()
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

结果

 import time
from threading import Thread, Lock def eat1(name, lock):
lock.acquire()
print(f'{name}拿到叉子了')
print(f'{name}拿到面条了')
print(f'{name}吃面')
lock.release() def eat2(name, lock):
lock.acquire()
print(f'{name}拿到面条了')
time.sleep(1)
print(f'{name}拿到叉子了')
print(f'{name}吃面')
lock.release() noodle_fork_lock = Lock()
Thread(target=eat1, args=('alex', noodle_fork_lock)).start()
Thread(target=eat2, args=('wusir', noodle_fork_lock)).start()
Thread(target=eat1, args=('yuan', noodle_fork_lock)).start()
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、池

未完待续。。。

python_线程的开启、守护线程、锁、死锁、事件、定时器、条件、队列、池的更多相关文章

  1. Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量

    Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程:    1.线程是一堆指令,是操作系统调度 ...

  2. python 线程(创建2种方式,锁,死锁,递归锁,GIL锁,守护进程)

    ###############总结############ 线程创建的2种方式(重点) 进程:资源分配单位    线程:cpu执行单位(实体) 线程的创建和销毁的开销特别小 线程之间资源共享,是同一个 ...

  3. Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁

    Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线程join.守护线程.线程互斥锁 目录 Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线 ...

  4. 线程 Thread Runnable 守护线程 join MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. Java多线程系列--“基础篇”10之 线程优先级和守护线程

    概要 本章,会对守护线程和线程优先级进行介绍.涉及到的内容包括:1. 线程优先级的介绍2. 线程优先级的示例3. 守护线程的示例 转载请注明出处:http://www.cnblogs.com/skyw ...

  6. java的守护线程与非守护线程

    最近重新研究Java基础知识,发现以前太多知识知识略略带过了,比较说Java的线程机制,在Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) ,(PS:以 ...

  7. Java中的守护线程和非守护线程(转载)

    <什么是守护线程,什么是非守护线程> Java有两种Thread:"守护线程Daemon"(守护线程)与"用户线程User"(非守护线程). 用户线 ...

  8. Java多线程-线程的调度(守护线程)

    本文转自http://www.cnblogs.com/linjiqin/p/3210004.html 感谢作者 守护线程与普通线程写法上基本没啥区别,调用线程对象的方法setDaemon(true), ...

  9. Python线程:线程的调度-守护线程

    Python线程:线程的调度-守护线程   守护线程与普通线程写法上基本么啥区别,调用线程对象的方法setDaemon(true),则可以将其设置为守护线程.在python中建议使用的是thread. ...

  10. Java多线程(十)——线程优先级和守护线程

    一.线程优先级的介绍 java 中的线程优先级的范围是1-10,默认的优先级是5.“高优先级线程”会优先于“低优先级线程”执行. java 中有两种线程:用户线程和守护线程.可以通过isDaemon( ...

随机推荐

  1. 6. svg学习笔记-路径

    路径相比于多边形<polygon>元素具有更强绘图能力,<polygon>元素可以绘制任意的多边形,而路径可以绘制任意的轮廓线,是线段,曲线,圆弧的组合形式.svg中可以使用& ...

  2. [Hive_3] Hive 建表指定分隔符

    0. 说明 Hive 建表示例及指定分隔符 1. Hive 建表 Demo 在 Hive 中输入以下命令创建表 user2 create table users2 (id int, name stri ...

  3. PXE 自动安装物理机 (DHCP服务由路由提供, 不能再配置)

    目录 1. PXE 自动安装物理机 (DHCP服务由路由提供, 不能再配置) 1.1. 需要的软件 1.2. 启动 proxy dhcp 服务 1.3. 关键的几个配置文件 PXE 自动安装物理机 ( ...

  4. June 17. 2018, Week 25th. Sunday

    Dad is and always will be my living, breathing superhero. 在我眼里,爸爸是现实版的超级英雄,现在.将来,永远都是. From Bindi Ir ...

  5. Beta阶段 - 博客链接合集

    Beta阶段 - 博客链接合集 项目Github地址 安卓端(Stardust):https://github.com/StardustProject/Stardust 服务器端(Gravel):ht ...

  6. ECharts图表之柱状折线混合图

    Echarts 官网主页  http://echarts.baidu.com/index.html Echarts 更多项目案例  http://echarts.baidu.com/echarts2/ ...

  7. P1678 烦恼的高考志愿(二分)

    emmmm,我感觉我在解题的过程中还是有点吃亏的,因为,我知道是二分,只是大概知道怎么分,没有管这道到底是需要怎样的二分.然后在题上卡了很久. 思路:要找到填报学校的录取线x和自己的分数y的绝对值最小 ...

  8. mysql备份命令

    mysql备份命令如下: 备份多个数据库可以使用如下命令: mysqldump -uroot -p123456 --databases test1 test2 test3 > /home/tes ...

  9. Codechef CNTL Counting is life 生成函数

    传送门--Vjudge 第一问很氵,如果\(K,N\)同奇偶就是\(2^K-1\),否则就是\(2^K-2\) 第二问似乎是可重排列,考虑指数型生成函数. 如何限制某些数必须要出现奇数/偶数次?考虑\ ...

  10. BZOJ3601 一个人的数论 莫比乌斯反演、高斯消元/拉格朗日插值

    传送门 题面图片真是大到离谱-- 题目要求的是 \(\begin{align*}\sum\limits_{i=1}^N i^d[gcd(i,n) == 1] &= \sum\limits_{i ...