博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第十五章、Python多线程之信号量和GIL
阅读量:5291 次
发布时间:2019-06-14

本文共 2496 字,大约阅读时间需要 8 分钟。

目录

第十五章、Python多线程之信号量和GIL

1. 信号量(Semaphore)

信号量用来控制线程并发数的,Semaphore管理一个内置的计数 器,每当调用acquire()时-1,调用release()时+1。计数器不能小于0,当计数器为 0时,acquire()将阻塞线程至同步锁定状态,直到其他线程调用release()。其实就是控制最多几个线程可以操作同享资源。

import threadingimport timesemaphore = threading.Semaphore(5)def func():    if semaphore.acquire():        print (threading.currentThread().getName() + '获取共享资源')        time.sleep(2)        semaphore.release()for i in range(10)  t1 = threading.Thread(target=func)  t1.start()--------------------------------------------------Thread-1获取共享资源Thread-2获取共享资源Thread-3获取共享资源Thread-4获取共享资源Thread-5获取共享资源Thread-6获取共享资源Thread-8获取共享资源Thread-7获取共享资源Thread-9获取共享资源Thread-10获取共享资源

上面一个简单的例子就是创建10个线程,让每次只让5个线程去执行func函数。

结果:5个线程一批一批的执行打印,中间停格2s

2. GIL

含义:全局解释器锁 。

作用:无论你启多少个线程,你有多少个cpu, Python在执行的时候只会的在同一时刻只允许一个线程(线程之间有竞争)拿到GIL在一个cpu上运行,当线程遇到IO等待或到达者轮询时间的时候,cpu会做切换,把cpu的时间片让给其他线程执行,cpu切换需要消耗时间和资源,所以计算密集型的功能(比如加减乘除)不适合多线程,因为cpu线程切换太多,IO密集型比较适合多线程。

任务:

  • IO密集型(各个线程都会都各种的等待,如果有等待,线程切换是比较适合的),也可以采用可以用多进程+协程

  • 计算密集型(线程在计算时没有等待,这时候去切换,就是无用的切换),python不太适合开发这类功能

    ​ 我们前面举得例子里面模拟了sleep操作,其实就是相当于遇到IO,这种场景用多线程是可以增加性能的,但是如果我们用多线程来计算数据的计算,性能反而会降低。

证明一下:

from threading import Threadfrom multiprocessing import Processimport time#计算密集型def work1():    res=0    for i in range(100000000): #1+8个0        res*=iif __name__ == '__main__':    t_list = []    start = time.time()    for i in range(4):        # t = Thread(target=work1)        t = Process(target=work1)        t_list.append(t)        t.start()    for t in t_list:        t.join()    end = time.time()    # print('多线程',end-start) # 多线程 15.413789510726929    print('多进程',end-start) # 多进程 4.711405515670776
from threading import Threadfrom multiprocessing import Processimport time# io密集型def work1():    x = 1+1    time.sleep(5)if __name__ == '__main__':    t_list = []    start = time.time()    for i in range(4):        t = Thread(target=work1)        # t = Process(target=work1)        t_list.append(t)        t.start()    for t in t_list:        t.join()    end = time.time()    print('多线程',end-start) #  多线程 5.002625942230225    # print('多进程',end-start) # 多进程 5.660863399505615

说明:

在Cpython解释器中有一把GIL锁(全局解释器锁),GIl锁本质是一把互斥锁。导致了同一个进程下,同一时间只能运行一个线程,无法利用多核优势.同一个进程下多个线程只能实现并发不能实现并行.为什么要有GIL?因为cpython自带的垃圾回收机制不是线程安全的,所以要有GIL锁.导致了同一个进程下,同一时间只能运行一个线程,无法利用多核优势.分析:我们有四个任务需要处理,处理方式肯定是要玩出并发的效果,解决方案可以是:方案一:开启四个进程方案二:一个进程下,开启四个线程计算密集型 推荐使用多进程 每个都要计算10s 多线程 在同一时刻只有一个线程会被执行,也就意味着每个10s都不能省,分开每个都要计算10s,共40.ns 多进程 可以并行的执行多个线程,10s+开启进程的时间

转载于:https://www.cnblogs.com/demiao/p/11545466.html

你可能感兴趣的文章
数据结构中线性表的基本操作-合并两个线性表-依照元素升序排列
查看>>
使用pager进行分页
查看>>
吐医疗器械研发可配置性需求的槽点
查看>>
UVA - 1592 Database
查看>>
机器翻译评价指标 — BLEU算法
查看>>
机器学习基石(9)--Linear Regression
查看>>
Min Stack
查看>>
从LazyPhp说起
查看>>
Fine Uploader文件上传组件
查看>>
Spring Boot与Spring的区别
查看>>
查看linux 之mysql 是否安装的几种方法
查看>>
javascript中的传递参数
查看>>
objective-c overview(二)
查看>>
python查询mangodb
查看>>
软件测试(基础理论一)摘
查看>>
CF327E Axis Walking
查看>>
关于eclipse maven引入第三方jar包后如何下载源代码
查看>>
no-sql数据库之redis
查看>>
关于浏览器内核的一些小知识,明明白白选浏览器!-
查看>>
2018年6月1日学习内容概要
查看>>