ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GIL全局解释器锁与IO模型

2022-01-17 22:04:35  阅读:141  来源: 互联网

标签:解释器 self 线程 IO time print import GIL


内容概要

  • GIL全局解释器锁(重要理论)
  • 验证GIL的存在及功能
  • 验证python多线程是否有用
  • 死锁现象
  • 进程池与线程池(使用频率较高)
  • IO模型(理论部分)
可参考:
    https://www.bilibili.com/video/BV1QE41147hU?p=500

内容详细

GIL全局解释器锁

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple 
native threads from executing Python bytecodes at once. This lock is necessary mainly 
because CPython’s memory management is not thread-safe. (However, since the GIL 
exists, other features have grown to depend on the guarantees that it enforces.)
"""
1.python解释器其实有很多版本(默认肯定使用的是CPython)
	解释器种类:Cpython、Jpython、pypython
	
在Cpython中GIL全局解释器锁其实也是一把互斥锁,主要用于阻止同一个进程下的多个线程同时被运行(python的多线程无法使用多核优势)
GIL肯定存在于Cpython解释器中 主要原因就在于Cpython解释器的内存管理不是线程安全的

2.内容管理>>>垃圾回收机制
	引用计数
	标记清除
	分代回收
"""
1.GIL是Cpython解释器的特点
2.python同一个进程内的多个线程无法利用多核优势(不能并行但是可以并发)
3.同一进程内的多个线程要想运行必须先抢GIL锁
4.所有的解释型语言几乎都无法实现同一个进程下的多个线程同时被运行

验证GIL的存在

from threading import Thread
import time

m = 100

def test():
    global m
    tmp = m
    # time.sleep(1)  # 99
    tmp -= 1
    m = tmp


for i in range(100):
    t = Thread(target=test)
    t.start()

time.sleep(3)
print(m)  # 0

"""
同一进程下的多个线程虽然有GIL的存在不会出现并行的效果
但是如果线程内有IO操作还是会造成数据的错乱 这个时候需要我们额外的添加互斥锁
"""

死锁现象

from threading import Thread, Lock
import time

A = Lock()
B = Lock()


class MyThread(Thread):
    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        A.acquire()
        print('%s 抢到了A锁' % self.name)
        B.acquire()
        print('%s 抢到了B锁' % self.name)
        time.sleep(1)
        B.release()
        print('%s 释放了B锁' % self.name)
        A.release()
        print('%s 释放了A锁' % self.name)

    def func2(self):
        B.acquire()
        print('%s 抢到了B锁' % self.name)
        A.acquire()
        print('%s 抢到了A锁' % self.name)
        time.sleep(1)
        A.release()
        print('%s 释放了A锁' % self.name)
        B.release()
        print('%s 释放了B锁' % self.name)


for i in range(10):
    obj = MyThread()
    obj.start()
    
"""
就算知道锁的特性及使用方法 也不要轻易的使用 因为容易出现锁死的现象
"""

python多线程是否没用

# 是否有用需要看情况而定(程序的类型)
# IO密集型
	eg:四个任务 每个任务耗时10s
        开设多进程没有太大的优势	10s+
        	遇到IO就需要切换 并且开设进程还需要申请内存空间和拷贝代码
		开设多线程有优势
        	不需要消耗额外的资源	10s+

# 计算密集型
	eg:四个任务	每个任务耗时10s
        开设多线程可以利用多核优势	10s+
        开设多线程无法利用多核优势	40s+
        
"""
多进程结合多线程
"""
"""IO密集型"""
from multiprocessing import Process
from threading import Thread
import threading
import os,time


def work():
    time.sleep(2)


if __name__ == '__main__':
    l = []
    print(os.cpu_count())  # 获取本机CPU核数  8核
    start = time.time()
    for i in range(400):
        # p = Process(target=work)  # 耗时22.46s多 大部分时间耗费在创建进程上
        p = Thread(target=work)  # 耗时2.07s多 
        l.append(p)
        p.start()

    for p in l:
        p.join()
        stop = time.time()
        print('run time is %s'%(stop-start))
        
"""计算密集型"""
from multiprocessing import Process
from threading import Thread
import os, time


def work():
    res = 0
    for i in range(100000000):
        res *= 1


if __name__ == '__main__':
    l = []
    print(os.cpu_count())  # 本机为6核
    start = time.time()
    for i in range(8):
        # p = Process(target=work)  # 耗时17.13s多
        p = Thread(target=work)  # 耗时47.74s多
        l.append(p)
        p.start()
    for p in l:
        p.join()
    stop = time.time()
    print('run time is %s' % (stop - start))

进程池与线程池

思考:能否无限制的开设进程或线程???
    肯定是不能无限制开设的
    	如果单从技术层面上来说无限开设肯定是可以的并且是最高效的
        但是从硬件层面上来说是无法实现的(硬件的发展永远赶不上软件的发展速度)
        
池
	在保证计算机硬件不崩溃的前提下开设多进程和多线程
    	降低了程序的运行效率但是保证了计算机硬件的安全
进程池与线程池
	进程池:提前开设了固定个数的进程 之后反复调用这些进程完成工作(后续不在开设新的)
    线程池:提前开设了固定个数的线程 之后反复调用这些线程完成工作(后续不在开设新的)

标签:解释器,self,线程,IO,time,print,import,GIL
来源: https://www.cnblogs.com/henry1998/p/15815495.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有