进程、线程与GIL全局解释器锁详解

进程与线程的关系:

1.   线程是最小的调度单位
2.  进程是最小的管理单元
3.  一个进程必须至少一个线程
4.  没有线程,进程也就不复存在

线程特点:

3     线程的并发是利用cpu上下文的切换(是并发,不是并行)
4     多线程执行的顺序是无序的
5     多线程共享全局变量
6     线程是继承在进程里的,没有进程就没有线程
7     GIL全局解释器锁
8     只要在进行耗时的IO操作的时候,能释放GIL,所以只要在IO密集型的代码里,用多线程就
9        很合适

线程详解:

import threading  # ---》导入模块
    # def func(n):
    #     print(‘task‘,n)
    # t = threading.Thread(target = func,args = (1,))
    # t.start()
    #
    #
    # for i in range(10):        ---》使t的内容循坏输出10行
    #     t = threading.Thread(target = func,args = (‘t-%s‘%i,))  ---》target=函数名 args要求以元组形式传参,当参数只有一个时,以(参数,)的格式传参。
    #     t.start()       ----》固定启动线程

    # 多线程共享全局变量

    # g=0    ---》设置一个全局变量
    # def test():
    #     global g              ----》线程共享全局变量时需要建立在声明global+全局变量上
    #     for i in range(10):
    #         g +=1
    #     print(g)
    # def test1():
    #     global g
    #     for i in range(10):
    #         g +=1
    #     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 = 0
def test1():
    global g_num
    lock.acquire()        ---》在循坏前锁上
    for i in range(100000):
        g_num +=1
    lock.release()      ----》赋值结束后解放锁
def test2():
    global g_num
    lock.acquire()
    for i in range(100000):
        g_num +=1
    lock.release()
t1=threading.Thread(target=test1)       ---》注意T要大写
t2=threading.Thread(target=test2)
t1.start()      #  导致结果不对的原因(1):主线程处理py文件速度比另外两个线程赋值速度快,在没赋值结束时就又开始新一轮的赋值
t2.start()

# 解决方法(1):
# 在后面加上两行
t1.join()   #----》即主线程等待每轮赋值结束后才重启下一轮赋值,但是这样也还是不对,只能让成功次数上升
t2.join()   # 因为赋值成功率不是100%,次数越多越有可能赋值失败。
print(g_num)

解决方法(2):
添加互斥锁:lock = threading.Lock() ,保证赋值成功,缺点是速度慢

进程详解:

# 一个程序运行起来之后,代码+用到的资源称之为进程,它是操作系统分配资源的基本单位,不仅可以通过线程完成多任务,进程也是可以的
# 进程之间是相互独立的,结果互不影响也无法共享全局变量,等待上一个进程结束,下一个进程再执行。
# cpu密集的时候适合用多进程
#cpu效率高,耗资源多,

import multiprocessing    --》导入进程模块
import time  ----》导入快捷键,将鼠标停在关键词上alt 加 enter 选择导入模块

def test1(n):
    time.sleep(2)       ---》两秒后打印执行任务完毕,再到第二个进程
    print(‘task‘,n)

def test2(n):
    time.sleep(2)
    print(‘task‘,n)
if __name__ == ‘__main__‘:    --->相当于调用test1()和test(2),这是主进程的作用
    p1 = multiprocessing.Process(target=test1,args=(1,))     --》注意P的大写
    p2 = multiprocessing.Process(target=test2,args=(1,))
    p1.start()      ---》此进程负责调用p1进程
    p2.start()     ---》负责调用p2进程

进程池:

import multiprocessing
import time
g_num = 0
def test1(n):
    for i in range(n):
        time.sleep(1)
        print(‘test1‘, i)

def test2(n):
    for i in range(n):
        time.sleep(1)
        print(‘test2‘, i)
def test3(n):
    for i in range(n):
        time.sleep(1)
        print(‘test3‘, i)

def test4(n):
    for i in range(n):
        time.sleep(1)
        print(‘test4‘, i)

if __name__ == ‘__main__‘:                  #此操作必须存在,不然无法调用
    pool = multiprocessing.Pool(3)          #把进程声明出来括号里不写东西说明无限制,如果写数字,就是最大的进程数,即允许几个进程并发。池外的串行
    pool.apply_async(test1,(5,))           #用pool去调用函数test1,参数为5格式为(5,)
    pool.apply_async(test2,(5,))
    pool.apply_async(test3,(5,))
    pool.apply_async(test4,(5,))          #以上三个进程并发处理,同时输出赋值,而4进程串行输出,因为在进程池外**
    pool.close()                            #close必须在join的前面
  

原文地址:https://www.cnblogs.com/zzzynx/p/10774817.html

时间: 2025-01-17 04:05:44

进程、线程与GIL全局解释器锁详解的相关文章

python第三十七天,GIL全局解释器锁*****,线程池与进程池 同步异步,阻塞与非阻塞,异步回调

GIL全局解释器锁 1.什么是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

Python之路-python(paramiko,进程和线程的区别,GIL全局解释器锁,线程,进程)

一.paramiko 二.进程.与线程区别 三.python GIL全局解释器锁 四.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 一.paramiko 用于远程连接并执行简单的命令 使用用户名密码连接: 1 import paramiko 2 3 # 创建SSH对象 4 ssh = paramiko.SSHClient() 5 # 允许连接不在know_hosts文件中的主机 6 ssh.set

GIL全局解释器锁和进程池.线程池

GIL全局解释器锁 GIL本质就是一把互斥锁,是夹在解释器身上的,同一个进程内的所有线程都需要先抢到GIl锁,才能执行解释器代码 GIL的优缺点: 优点:保证Cpython解释器内存管理的线程安全 缺点:同一个进程内所有的线程同一时刻只能有一个执行,也就是说Cpython解释器的多线程无法实现并行,无法取得多核优势 GIL与单线程 每个进程的内存空间中都有一份python解释器的代码,所以在单线程的情况下,GIL锁没有线程争抢,只有垃圾回收机制线程会定时获取GIL权限 GIL与多线程 有了GIL

10 并发编程-(线程)-GIL全局解释器锁&死锁与递归锁

一.GIL全局解释器锁 1.引子 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念. 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码.>有名的编译器例如GCC,INTEL C++,Visual C++等.Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行

TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q

TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q 一.TCP协议下的服务端并发 ''' 将不同的功能尽量拆分成不同的函数,拆分出来的功能可以被多个地方使用 TCP服务端实现并发 1.将连接循环和通信循环拆分成不同的函数 2.将通信循环做成多线程 ''' # 服务端 import socket from threading import Thread ''' 服务端 要有固定的IP和PORT 24小时不间断提供服务 能够支持并发 ''' server = sock

GIL全局解释器锁

1.什么是GIL全局解释器锁? GIL并不是Python的特性,而是CPython解释器的概念.Python完全可以不依赖于GIL. GIL本质是一把互斥锁,是加在CPython解释器身上的,同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2.为什么会有GIL? 为了利用多核,Python开始支持多线程,而解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁,于是有了GIL这把超级大锁. 简单的说GIL的存在更多的是历史原因. 3.GIL的影响 GIL的存在会对多线程的效率

Python 36 GIL全局解释器锁

一:GIL全局解释器锁介绍 在CPython中,全局解释器锁(或GIL)是一个互斥锁, 它阻止多个本机线程同时执行Python字节码.译文:之所以需要这个锁, 主要是因为CPython的内存管理不是线程安全的.(然而,由于GIL的存在, 其他特性已经变得依赖于它所执行的保证.) 1. 什么是GIL全局解释器锁GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行

python 并发编程 多线程 GIL全局解释器锁基本概念

首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念. 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码. >有名的编译器例如GCC,INTEL C++,Visual C++等.Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行. 像其中的JPython就没有GIL.然而因为CPython是大部分环境下默认的Python执行环境.所以在很多人的概

117 GIL全局解释器锁

一.GIL全局解释器锁 cpython中自带的GIL全局解释器,GIL本身就是一把互斥锁 重点:因为有了GIL全局解释器锁,导致了在同一进程的同一时刻只有一个线程在执行,无法利用多核优势 其实就算我们在程序中写了一个线程的并行操作,实际上GIL会因为垃圾回收机制的问题,操作系统调度的问题,会把并行的线程还是变成了串行,这正是这个GIL全局解释器锁导致了同一进程的同一时刻只有一个线程在运行, Python代码的执行由Python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主