本文目录:

一、GIL

二、关于GIL性能的讨论

三、计算密集测试

四、IO密集测试

五、GIL与互斥锁

六、进程池

七、进程什么时候算是空闲

八、线程池

一、GIL

什么叫GIL

全局解释器锁(GIL Global Interpreter Lock),锁就是线程里面那个锁,锁是为了避免资源竞争造成数据的错乱,python程序的执行过程,1.启动解释器进程  python.exe,
2.解析你的py文件并执行它,每个py程序中都必须有解释器参与解释器其实就是一堆代码,相当于多个线程要调用同一个解释器代码,共享以为竞争 ,竞争就要出事,所以给解释器加锁。
python 中内存管理依赖于 GC(一段用于回收内存的代码) 也需要一个线程
除了你自己开的线程 系统还有一些内置线程 就算你的代码不会去竞争解释器 内置线程也可能会竞争
所以必须加上锁 当一个线程遇到了IO 同时解释器也会自动解锁 去执行其他线程 CPU会切换到其他程序 x = obj +1
a = obj +1 2 x = None -1
a = None -1 0

二、关于GIL性能的讨论

"""
解释器加锁以后
将导致所有线程只能并发 不能达到真正的并行 意味着同一时间只有一个CPU在处理你的线程
给你的感觉是效率低 代码执行有两种状态
阻塞 i/o 失去CPU的执行权 (CPU等待IO完成)
非阻塞 代码正常执行 比如循环一千万次 中途CPU可能切换 很快会回来 (CPU在计算) 假如有32核CPU 要处理一个下载任务 网络速度慢 100k/s 文件大小为1024kb
如果你的代码中IO操作非常多 cpu性能不能直接决定你的任务处理速度 案例:
目前有三个任务 每个任务处理需一秒 获取元数据需要一小时
3个CPU 需要 一小时1秒
1个cpu 需要 一小时3秒 在IO密集的程序中 CPU性能无法直接决定程序的执行速度 python就应该干这种活儿
在计算密集的程序中 CPU性能可以直接决定程序的执行速度 """

三、计算密集测试

from threading import Thread
from multiprocessing import Process
import time # 计算密集任务 def task1():
sum = 1
for i in range(10000000):
sum *= i def task2():
sum = 1
for i in range(10000000):
sum *= i def task3():
sum = 1
for i in range(10000000):
sum *= i def task4():
sum = 1
for i in range(10000000):
sum *= i def task5():
sum = 1
for i in range(10000000):
sum *= i def task6():
sum = 1
for i in range(10000000):
sum *= i if __name__ == '__main__': # 开始时间
st_time = time.time()
# 多线程情况下
# t1 = Thread(target=task1)
# t2 = Thread(target=task2)
# t3 = Thread(target=task3)
# t4 = Thread(target=task4)
# t5 = Thread(target=task5)
# t6 = Thread(target=task6) t1 = Process(target=task1)
t2 = Process(target=task2)
t3 = Process(target=task3)
t4 = Process(target=task4)
t5 = Process(target=task5)
t6 = Process(target=task6) t1.start()
t2.start()
t3.start()
t4.start()
t5.start()
t6.start()
#
# t1.join()
# t2.join()
# t3.join()
# t4.join()
# t5.join()
# t6.join() print(time.time() - st_time)

四、IO密集测试

from threading import Thread
from multiprocessing import Process
import time # 计算密集任务
def task1():
time.sleep(3) def task2():
time.sleep(3) def task3():
time.sleep(3) def task4():
time.sleep(3) def task5():
time.sleep(3) def task6():
time.sleep(3) if __name__ == '__main__': # 开始时间
st_time = time.time()
# 多线程情况下
# t1 = Thread(target=task1)
# t2 = Thread(target=task2)
# t3 = Thread(target=task3)
# t4 = Thread(target=task4)
# t5 = Thread(target=task5)
# t6 = Thread(target=task6) t1 = Process(target=task1)
t2 = Process(target=task2)
t3 = Process(target=task3)
t4 = Process(target=task4)
t5 = Process(target=task5)
t6 = Process(target=task6) t1.start()
t2.start()
t3.start()
t4.start()
t5.start()
t6.start() # t1.join()
# t2.join()
# t3.join()
# t4.join()
# t5.join()
# t6.join() print(time.time() - st_time)

五、GIL与互斥锁

from  threading import Thread,Lock
import time mutex = Lock()
num = 1
def task():
global num
# print(num)
mutex.acquire()
temp = num
print(temp)
time.sleep(1) # 当你们线程中出现io时 GIL锁就解开
num = temp + 1
mutex.release() # 线程任务结束时GIL锁解开 t1 = Thread(target=task,) t2 = Thread(target=task,)
t1.start()
t2.start()
t1.join()
t2.join()
print(num) #
# GIL 和 自定义互斥锁的区别
# 全局锁不能保证自己开启的线程安全 但是保证解释器中的数据的安全的
# GIL 在线程调用解释器时 自动加锁 在IO阻塞时或线程代码执行完毕时 自动解锁
#

六、进程池

"""
进程池
就是一个装进程的容器
为什么出现
当进程很多的时候方便管理进程
什么时候用?
当并发量特别大的时候 列入双十一
很多时候进程是空闲的 就让他进入进程池 让有任务处理时才从进程池取出来使用
进程池使用
ProcessPoolExecutor类
创建时指定最大进程数 自动创建进程
调用submit函数将任务提交到进程池中
创建进程是在调用submit后发生的 总结一下:
进程池可以自动创建进程
进程限制最大进程数
自动选择一个空闲的进程帮你处理任务
遗留问题 进程什么时候算是空闲 """
import socket
from multiprocessing import Process from concurrent.futures import ProcessPoolExecutor # 收发数据
def task(c, addr):
while True:
try:
data = c.recv(1024)
print(data.decode("utf-8"))
if not data:
c.close()
break
c.send(data.upper())
except Exception:
print("连接断开")
c.close()
break if __name__ == '__main__': server = socket.socket() server.bind(("127.0.0.1",65535)) server.listen(5) # 创建一个进程池 默认为CPU个数
pool = ProcessPoolExecutor() while True:
c,addr = server.accept()
# p = Process(target=task,args=(c,addr))
# p.start()
pool.submit(task,c,addr)

七、进程什么时候算是空闲

from concurrent.futures import  ProcessPoolExecutor

import os,time,random

def task():
time.sleep(random.randint(1,2))
print(os.getpid()) def run():
pool = ProcessPoolExecutor(2)
for i in range(30):
pool.submit(task) if __name__ == '__main__':
run()

八、线程池

from concurrent.futures import  ProcessPoolExecutor,ThreadPoolExecutor
from threading import current_thread import os,time,random def task():
time.sleep(random.randint(1,2))
print(current_thread()) def run():
# 默认为cpu核心数 * 5
pool = ThreadPoolExecutor(3)
for i in range(30):
pool.submit(task) if __name__ == '__main__':
run()

并发编程: GIL锁、GIL与互斥锁区别、进程池与线程池的区别的更多相关文章

  1. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  2. Java并发编程实战(3)- 互斥锁

    我们在这篇文章中主要讨论如何使用互斥锁来解决并发编程中的原子性问题. 目录 概述 互斥锁模型 互斥锁简易模型 互斥锁改进模型 Java世界中的互斥锁 synchronized中的锁和锁对象 synch ...

  3. java并发编程实战《三》互斥锁(上)

    互斥锁(上):解决原子性问题 原子性问题的源头是线程切换,操作系统做线程切换是依赖 CPU 中断的,所以禁止 CPU 发生中断就能够禁止线程切换. 在早期单核 CPU 时代,这个方案的确是可行的,而且 ...

  4. java并发编程实战《四》互斥锁(下)

    互斥锁(下):如何用一把锁保护多个资源?    一把锁可以保护多个资源,但是不能用多把锁来保护一个资源. 那如何保护多个资源? 当我们要保护多个资源时,首先要区分这些资源是否存在关联关系. 如下代码 ...

  5. Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池

    Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...

  6. GIL与普通互斥锁区别,死锁现象,信号量,event事件,进程池与线程池,协程

    GIL与普通互斥锁区别 GIL锁和互斥锁的异同点 相同: 都是为了解决解释器中多个线程资源竞争的问题 异: 1.互斥锁是Python代码层面的锁,解决Python程序中多线程共享资源的问题(线程数据共 ...

  7. GIL锁、进程池与线程池

    1.什么是GIL? 官方解释: ''' In CPython, the global interpreter lock, or GIL, is a mutex that prevents multip ...

  8. GIL锁、进程池与线程池、同步异步

    GIL锁定义 GIL锁:Global Interpreter Lock  全局解释器 本质上是一把互斥锁 官方解释: 在CPython中,这个全局解释器锁,也称为GIL,是一个互斥锁,防止多个线程在同 ...

  9. GIL解释锁及进程池和线程池

    官方介绍 ''' 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple nati ...

  10. GIL全局解释器锁、死锁现象、python多线程的用处、进程池与线程池理论

    昨日内容回顾 僵尸进程与孤儿进程 # 僵尸进程: 所有的进程在运行结束之后并不会立刻销毁(父进程需要获取该进程的资源) # 孤儿进程: 子进程正常运行 但是产生该子进程的父进程意外死亡 # 守护进程: ...

随机推荐

  1. 安卓控件支持HTML标签

    http://www.cnblogs.com/xqxacm/p/5092557.html

  2. Python os 使用

    python os 使用 1. 获取文件所在路径 import os os.path.dirname(__file__)  获取当前文件的所在路径 print (os.path.dirname(os. ...

  3. Leetcode之动态规划(DP)专题-122. 买卖股票的最佳时机 II(Best Time to Buy and Sell Stock II)

    Leetcode之动态规划(DP)专题-122. 买卖股票的最佳时机 II(Best Time to Buy and Sell Stock II) 股票问题: 121. 买卖股票的最佳时机 122. ...

  4. python录音并调用百度语音识别接口

    #!/usr/bin/env python import requests import json import base64 import pyaudio import wave import os ...

  5. Excel小技巧(随机点名)

    如图,想要做一个随机点名的表格,同样可以石头剪刀布的场合,随机选人. 如何做呢? 第一步,填好想要的数据 第二步,在空的位置输入=INDIRECT("A"&RANDBETW ...

  6. [bzoj1733][Usaco2005 feb]Secret Milking Machine 神秘的挤奶机_网络流

    [Usaco2005 feb]Secret Milking Machine 神秘的挤奶机 题目大意:约翰正在制造一台新型的挤奶机,但他不希望别人知道.他希望尽可能久地隐藏这个秘密.他把挤奶机藏在他的农 ...

  7. DOS bcp

    C:\>bcp /?用法: bcp {dbtable | query} {in | out | queryout | format} 数据文件  [-m 最大错误数]             [ ...

  8. spring-boot 连接数据库(六)

    环境 jdk 6 tomcat 6.0.53 sts 4.4.2 maven 3.2.5 mysql 5.7 准备 接下来的数据库操作基于 mysql,所以需要一套可用的 mysql 环境. 引入 j ...

  9. PAT A1019 General Palindromic Number (20 分)

    AC代码 #include <cstdio> const int max_n = 1000; long long ans[max_n]; int num = 0; void change( ...

  10. 可取消可报告进度的Task

    using System; using System.Threading; using System.Threading.Tasks; using System.Windows; namespace ...