1.线程: 一个进程可以有多个线程,共享一个进程的资源;

2.进程线程的区别:

   进程是资源分配的最小单位,线程是程序执行的最小单位

3.python中线程模块threading, 提供的类: Thread, Lock, Rlock, Semaphore, Event, 等等

4.线程的创建方式

# 第一种
# from threading import Thread
# def f1(s):
# print('我是%s' % s)
# def f2(s):
# print('我是%s' % s)
#
# if __name__ == '__main__':
# t = Thread(target=f1, args=(1,))
# t1 = Thread(target=f1, args=(2,))
# t.start()
# t1.start()
# print('我是主线程') # 第二种
from threading import Thread class MyThread(Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print('%s今天还是不能皮' % self.name)
if __name__ == '__main__':
t = MyThread('Jerry')
t.start()
print('主线程')

6.查看线程的进程id(同进程查看方式一样)

import os
from threading import Thread
def f1(n):
print('1号', os.getpid())
print('%s号线程任务' % n)
def f2(n):
print('2号', os.getpid())
print('%s号线程任务' % n)
if __name__ == '__main__':
t1 = Thread(target=f1, args=(1,))
t2 = Thread(target=f2, args=(2,))
t1.start()
t2.start()
print('主线程', os.getpid())
print('主线程')

7. 在进程之间数据是空间隔离的, 而在线程中是数据共享的

import time
from threading import Thread # 通过对全局变量的修改来验证线程之间是数据共享的, 共享同一进程中的数据
num = 100
def f1():
time.sleep(3)
global num
num = 3
print('子线程的num', num) if __name__ == '__main__':
t = Thread(target=f1)
t.start()
t.join() # 等待子线程运行结束才继续向下执行
print('主线程的num', num)

8.多进程和多线程的效率对比

对于io密集型的, 多线程的时间较快

def f1():
time.sleep(1) #io密集型 if __name__ == '__main__':
# 查看一下20个线程执行20个任务的执行时间
t_s_time = time.time()
t_list = []
for i in range(5):
t = Thread(target=f1,)
t.start()
t_list.append(t)
[tt.join() for tt in t_list]
t_e_time = time.time()
t_dif_time = t_e_time - t_s_time
# 查看一下20个进程执行同样的任务的执行时间
p_s_time = time.time()
p_list = []
for i in range(5):
p = Process(target=f1,)
p.start()
p_list.append(p)
[pp.join() for pp in p_list]
p_e_time = time.time()
p_dif_time = p_e_time - p_s_time
print('多线程的执行时间:', t_dif_time)
print('多jincheng的执行时间:', p_dif_time)

计算型:

import time
from threading import Thread
from multiprocessing import Process def f1():
# 计算型:
n = 10
for i in range(10000000):
n = n + i
if __name__ == '__main__':
# 查看一下20个线程执行20个任务的执行时间
t_s_time = time.time()
t_list = []
for i in range(5):
t = Thread(target=f1,)
t.start()
t_list.append(t)
[tt.join() for tt in t_list]
t_e_time = time.time()
t_dif_time = t_e_time - t_s_time
# 查看一下20个进程执行同样的任务的执行时间
p_s_time = time.time()
p_list = []
for i in range(5):
p = Process(target=f1,)
p.start()
p_list.append(p)
[pp.join() for pp in p_list]
p_e_time = time.time()
p_dif_time = p_e_time - p_s_time
print('多线程的执行时间:', t_dif_time)
print('多jincheng的执行时间:', p_dif_time)

9.锁,同步,互斥锁 为了保护多线成中数据的完整性和线程间状态的同步.(同进程的锁一样)

在线程锁中, 会产生死锁现象. 同时抢锁

import time
from threading import Thread, Lock, RLock
def f1(locA, locB):
# print('xxxx')
# time.sleep(0.1)
locA.acquire()
print('f1>>1号抢到了A锁') time.sleep(1)
locB.acquire()
print('f1>>1号抢到了B锁')
locB.release() locA.release()
def f2(locA, locB):
print('')
time.sleep(0.1)
locB.acquire()
print('f2>>2号抢到了B锁')
locA.acquire()
time.sleep(1)
print('f2>>2号抢到了A锁')
locA.release()
locB.release()
if __name__ == '__main__':
locA = Lock()
locB = Lock()
t1 = Thread(target=f1, args=(locA, locB))
t2 = Thread(target=f2, args=(locA, locB))
t1.start()
t2.start()

递归锁解决了 死锁现象

import time
from threading import Thread, Lock, RLock def f1(locA, locB):
print('xxxxx')
time.sleep(0.1)
locA.acquire()
print('f1>>>1号抢到了A锁')
time.sleep(1)
locB.acquire()
print('f1>>>2号抢到了B锁')
locB.release()
locA.release()
def f2(locA, locB):
print('')
time.sleep(0.1)
locB.acquire()
print('f2>>>1号抢到了A锁')
time.sleep(1)
locA.acquire()
print('f2>>>2号抢到了B锁')
locA.release()
locB.release()
if __name__ == '__main__':
locA = locB = RLock()
t1 = Thread(target=f1, args=(locA, locB))
t2 = Thread(target=f2, args=(locB, locA))
t1.start()
t2.start()

10.多线程的程序不结束 和 多进程的程序不结束的区别

守护进程:主进程代码执行运行结束,守护进程随之结束
守护线程:守护线程会等待所有非守护线程运行结束才结束
import time
from threading import Thread
from multiprocessing import Process # 守护进程:主进程代码执行运行结束,守护进程随之结束
# 守护线程:守护线程会等待所有非守护线程运行结束才结束
def f1():
time.sleep(2)
print('一号线程') def f2():
time.sleep(3)
print('二号线程')
def f3():
time.sleep(2)
print('一号进程') def f4():
time.sleep(3)
print('二号进程')
if __name__ == '__main__':
# t1 = Thread(target=f1,)
# t2 = Thread(target=f2,)
# # t1.daemon = True #  等非守护线程结束,守护线程才会结束 结果: 主线程结束 一号线程 二号线程
# t2.daemon = True # 结果: 主线程结束 一号线程
# t1.start()
# t2.start()
# print('主线程结束')
p1 = Process(target=f3,)
p2 = Process(target=f4,)
# p1.daemon = True # 结果: 主进程 二号线程
p2.daemon= True # 结果: 主进程 一号线程
p1.start()
p2.start()
print('主进程')

11. GIL锁 :  cpython解释器上的一把互斥锁, Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核

Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

 

最新文章

  1. Less配置环境
  2. Android中设定EditText的输入长度(转)
  3. WebService之Axis2(5):会话(Session)管理
  4. Centos6.5以下Samba服务配置
  5. QMVC
  6. 图片添加border 不占用图片的大小
  7. slf4j(simple logging facade for java)
  8. 201521123100 《java程序设计》第12周学习总结
  9. 多线程并发之java内存模型JMM
  10. informix存储过程笔记
  11. spring启动component-scan类扫描加载过程(转)
  12. selenium之使用chrome浏览器测试(附chromedriver与chrome的对应关系表)
  13. Adobe Photoshop安装
  14. 最优路径算法合集(附python源码)(原创)
  15. AngularJS学习之旅—AngularJS 指令(三)
  16. go import 使用方法记录
  17. network is unreachable 网关PING不通解决办法
  18. 如何把checkbox做成radio一样的单选效果
  19. python六十一课——高阶函数之reduce
  20. 这些linux技巧大大提高你的工作效率

热门文章

  1. 关于如何使`(a === 1 && a === 2 && a === 3)`返回`true`问题的思考
  2. 学习react
  3. [EXP]phpBB 3.2.3 - Remote Code Execution
  4. ubuntu下 远程连接windows服务器工具Remmina
  5. pycharm 安装第三方库报错:AttributeError: 'module' object has no attribute 'main'
  6. 《深入分析Linux内核源代码》读书、私藏笔记大放送
  7. 高手速成android开源项目【View篇】
  8. SQL 必知必会·笔记<2>检索和排序数据
  9. quartz配置参数org.quartz.jobStore.misfireThreshold含义解释
  10. 安装clickhouse缺少依赖libicudata.so.50()(64bit)