进程、线程与GIL全局解释器锁详解
(1)python下多线程的限制以及多进程中传递参数的方式
python多线程有个全局解释器锁(global interpreter lock),这个锁的意思是任一时间只能有一个线程使用解释器,跟单cpu跑多个程序一个意思,大家都是轮着用的,这叫“并发”,不是“并行”。
多进程间共享数据,可以使用 multiprocessing.Value 和 multiprocessing.Array
(2)python多线程与多进程的区别
在UNIX平台上,当某个进程终结之后,该进程需要被其父进程调用wait,否则进程成为僵尸进程(Zombie)。所以,有必要对每个Process对象调用join()方法 (实际上等同于wait)。对于多线程来说,由于只有一个进程,所以不存在此必要性。
多进程应该避免共享资源。在多线程中,我们可以比较容易地共享资源,比如使用全局变量或者传递参数。在多进程情况下,由于每个进程有自己独立的内存空间,以上方法并不合适。此时我们可以通过共享内存和Manager的方法来共享资源。但这样做提高了程序的复杂度,并因为同步的需要而降低了程序的效率。
进程与线程的关系:
. 线程是最小的调度单位
. 进程是最小的管理单元
. 一个进程必须至少一个线程
. 没有线程,进程也就不复存在
线程特点:
线程的并发是利用cpu上下文的切换(是并发,不是并行)
多线程执行的顺序是无序的
多线程共享全局变量
线程是继承在进程里的,没有进程就没有线程
GIL全局解释器锁
只要在进行耗时的IO操作的时候,能释放GIL,所以只要在IO密集型的代码里,用多线程就
很合适
线程详解:
import threading # ---》导入模块
# def func(n):
# print('task',n)
# t = threading.Thread(target = func,args = (,))
# t.start()
#
#
# for i in range(): ---》使t的内容循坏输出10行
# t = threading.Thread(target = func,args = ('t-%s'%i,)) ---》target=函数名 args要求以元组形式传参,当参数只有一个时,以(参数,)的格式传参。
# t.start() ----》固定启动线程 # 多线程共享全局变量 # g= ---》设置一个全局变量
# def test():
# global g ----》线程共享全局变量时需要建立在声明global+全局变量上
# for i in range():
# g +=
# print(g)
# def test1():
# global g
# for i in range():
# g +=
# print(g)
# t1=threading.Thread(target=test) ---->用线程调用test函数的结果,没有参数时,只需要输入target就行
# t2=threading.Thread(target=test1)
# t1.start()
# t2.start()
协程:
资源的自动切换,耗资源小,效率高。
GIL全局解释器锁:
#GIL全局解释器锁 ---》作用是保证最多只有一个线程在使用全局变量g_num,但是不保证赋值成功
lock = threading.Lock() ----》添加互斥锁,作用是使两个线程不再并发处理,使赋值成功,注意L要大写
g_num =
def test1():
global g_num
lock.acquire() ---》在循坏前锁上
for i in range():
g_num +=
lock.release() ----》赋值结束后解放锁
def test2():
global g_num
lock.acquire()
for i in range():
g_num +=
lock.release()
t1=threading.Thread(target=test1) ---》注意T要大写
t2=threading.Thread(target=test2)
t1.start() # 导致结果不对的原因():主线程处理py文件速度比另外两个线程赋值速度快,在没赋值结束时就又开始新一轮的赋值
t2.start() # 解决方法():
# 在后面加上两行
t1.join() #----》即主线程等待每轮赋值结束后才重启下一轮赋值,但是这样也还是不对,只能让成功次数上升
t2.join() # 因为赋值成功率不是100%,次数越多越有可能赋值失败。
print(g_num) 解决方法():
添加互斥锁:lock = threading.Lock() ,保证赋值成功,缺点是速度慢
进程详解:
# 一个程序运行起来之后,代码+用到的资源称之为进程,它是操作系统分配资源的基本单位,不仅可以通过线程完成多任务,进程也是可以的
# 进程之间是相互独立的,结果互不影响也无法共享全局变量,等待上一个进程结束,下一个进程再执行。
# cpu密集的时候适合用多进程
#cpu效率高,耗资源多, import multiprocessing --》导入进程模块
import time ----》导入快捷键,将鼠标停在关键词上alt 加 enter 选择导入模块 def test1(n):
time.sleep() ---》两秒后打印执行任务完毕,再到第二个进程
print('task',n) def test2(n):
time.sleep()
print('task',n)
if __name__ == '__main__': --->处理py文件,这是主进程的作用
p1 = multiprocessing.Process(target=test1,args=(,)) --》注意P的大写
p2 = multiprocessing.Process(target=test2,args=(,))
p1.start() ---》此进程负责调用p1进程
p2.start() ---》负责调用p2进程
进程池:
import multiprocessing
import time #进程池的并发必须导入和引用时间模块
g_num =
def test1(n):
for i in range(n):
time.sleep()
print('test1', i) def test2(n):
for i in range(n):
time.sleep()
print('test2', i)
def test3(n):
for i in range(n):
time.sleep()
print('test3', i) def test4(n):
for i in range(n):
time.sleep()
print('test4', i) if __name__ == '__main__': #此操作必须存在,不然无法调用
pool = multiprocessing.Pool() #把进程声明出来括号里不写东西说明无限制,如果写数字,就是最大的进程数,即允许几个进程并发。池外的串行
pool.apply_async(test1,(,)) #用pool去调用函数test1,参数为5格式为(,)
pool.apply_async(test2,(,))
pool.apply_async(test3,(,))
pool.apply_async(test4,(,)) #以上三个进程并发处理,同时输出赋值,而4进程串行输出,因为在进程池外**
pool.close()
pool.join() #close必须在join的前面
进程、线程与GIL全局解释器锁详解的更多相关文章
- Python自动化 【第九篇】:Python基础-线程、进程及python GIL全局解释器锁
本节内容: 进程与线程区别 线程 a) 语法 b) join c) 线程锁之Lock\Rlock\信号量 d) 将线程变为守护进程 e) Event事件 f) queue队列 g) 生 ...
- 【转】进程、线程、 GIL全局解释器锁知识点整理
转自:https://www.cnblogs.com/alex3714/articles/5230609.html 本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线 ...
- GIL全局解释器锁,线程池与进程池 同步异步,阻塞与非阻塞,异步回调
GIL全局解释器锁 1.什么是GIL 官方解释:'''In CPython, the global interpreter lock, or GIL, is a mutex that prevents ...
- Python之路-python(paramiko,进程和线程的区别,GIL全局解释器锁,线程)
一.paramiko 二.进程.与线程区别 三.python GIL全局解释器锁 四.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生 ...
- python 之 并发编程(守护线程与守护进程的区别、线程互斥锁、死锁现象与递归锁、信号量、GIL全局解释器锁)
9.94 守护线程与守护进程的区别 1.对主进程来说,运行完毕指的是主进程代码运行完毕2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕详细解释:1.主 ...
- GIL全局解释器锁、死锁现象、python多线程的用处、进程池与线程池理论
昨日内容回顾 僵尸进程与孤儿进程 # 僵尸进程: 所有的进程在运行结束之后并不会立刻销毁(父进程需要获取该进程的资源) # 孤儿进程: 子进程正常运行 但是产生该子进程的父进程意外死亡 # 守护进程: ...
- 10 并发编程-(线程)-GIL全局解释器锁&死锁与递归锁
一.GIL全局解释器锁 1.引子 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 首先需要明确的一点是GIL并不是Python的特性,它是在实现Pyt ...
- 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁
一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...
- python GIL全局解释器锁,多线程多进程效率比较,进程池,协程,TCP服务端实现协程
GIL全局解释器锁 ''' python解释器: - Cpython C语言 - Jpython java ... 1.GIL: 全局解释器锁 - 翻译: 在同一个进程下开启的多线程,同一时刻只能有一 ...
随机推荐
- 使用spark访问hive错误记录
在spark集群中执行./spark-shell时报以下错误: 18/07/23 10:02:39 WARN DataNucleus.Connection: BoneCP specified but ...
- scrapy输出的json文件中显示中文
scrapy用-o filename.json 输出时,会默认使用unicode编码,当内容为中文时,输出的json文件不便于查看,如下图: 可以在setting.py文件中修改默认的输出编码方式,只 ...
- 使用 requests
基本实例 #利用requests库发送get请求 import requests r = requests.get('http://httpbin.org/get') print(r.text) 利用 ...
- ImageUtil
package com.rscode.credits.util; import java.io.File; import java.io.IOException; import java.util.A ...
- 蓝桥每周一题之1. 3n+1 问题
[问题描述] 考虑如下的序列生成算法:从整数 n 开始,如果 n 是偶数,把它除以 2:如果 n 是奇数,把它乘 3 加1.用新得到的值重复上述步骤,直到 n = 1 时停止.例如,n = 22 时该 ...
- zznuoj 1195 : 猴子选大王(结构体专题)
题目描述 n只猴子围坐成一个圈,按顺时针方向从1到n编号.然后从1号猴子开始沿顺时针方向从1开始报数,报到m的猴子出局,再从刚出局猴子的下一个位置重新开始报数,如此重复,直至剩下一个猴子,它就是大王. ...
- 项目里如何访问AppDelegate
项目里面访问AppDelegate做全局变量用有好几种方式 最原始就是 AppDelegate *appDelegate = (AppDelegate *)[[UIApplication shared ...
- html5 知识点简单总结02
三个列表: 1.无序列表 默认样式 实心小圆点 ul type属性 "square" 实心方形 type属性 "circle" 空心圆 type属性 &q ...
- 搭建开发环境1)安装VMware Tools
1.安装Vmware Tools 安装VMware Tools ,在虚拟机中装Linux 一般都不是默认全屏这个就需要安装VMware Tools的插件或者写个脚本文件每次启动的时候自动调整分辨率的大 ...
- spring-aop思想实践demo
需求: 例如我们需要有一个类中每个方法执行前都需要做一个权限校验,必须是有特定权限的账号才能完成该方法的操作. 解决方案: 1.使用父类继承方式,书写该类的父类,然后在父类中定义一个checkPri的 ...