进程、线程与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: 全局解释器锁 - 翻译: 在同一个进程下开启的多线程,同一时刻只能有一 ...
随机推荐
- Centos7编译opencv3.4.1
Centos7编译opencv3.4.1 参考博客 https://blog.csdn.net/wjbwjbwjbwjb/article/details/79111996 1.配置epel源 yum ...
- liunx学习笔记
告知-----------------------------------grub启动时滚动的代码屏默认我们执行命令使用的为bash,unix使用的为csh能够通过service 程序名进行start ...
- hql和sql的一些区别
日期格式化查询的区别: selectSql.append(" AND DATE_FORMAT(o.createDate,\'%Y-%m-%d\') = :createDate"); ...
- BurpSuite工具抓取手机的流量
1.设置BurpSuite监听策略(和电脑区别不大就简单写了) 打开BurpSuite进入Proxy-Options界面,修改端口为8082.地址为第二项所有接口,点击OK 2.设置手机代理 首先保证 ...
- javascript中使用"<"符号,比较大小的是字符串或对象时正确的处理方法
<![CDATA[ var items=document.getElementsByTagName("li"); for(var i=0;i<items.length; ...
- Redis不支持ssl
一直在公司内部推荐redis做cache管理,今天偶然想起虽然C#没问题,可是c/c++没查过可不可行. 结果查了一下,还真tmd有问题,官方的c client版本只支持linux side的,根本没 ...
- 第一次博客作业(初识C++)
Q1:学习<C++语言程序设计>课程之前,你知道什么是编程吗?谈谈上这门课之前你对编程的理解,以及你对自己编程能力的评估. A1:开始课程之前,我认为编程是这样的:用计算机的语言写一份流程 ...
- python练习题3:N的多次方
N的多次方 描述 编写一个程序,计算输入数字N的0次方到5次方结果,并依次输出这6个结果,输出结果间用空格分隔.其中:N是一个整数或浮点数. print()函数可以同时输出多个信息,采用如下方法可以使 ...
- lua 匹配空白符
lua 支持的所有字符类: . 任意字符%s 空白符 空白字符一般包括空格.换行符\n.制表符\t以及回到行首符\r%p 标点字符%c 控制字符%d 数字%x 十六进制数字%z 代表0的字符% ...
- 20175202 《Java程序设计》迭代和JDB
一.任务详情 二.设计过程的问题及解决 1.程序编译时一直提示编译出现错误. 原因及解决:本以为声明对象和创建对象一起进行时,可以直接采用如zhubajie = new Xiyoujirenwu(); ...