TOP

GIL全局解释器锁、死锁、递归锁、线程队列(一)
2019-11-15 18:59:02 】 浏览:107次 本网站的内容取自网络,仅供学习参考之用,绝无侵犯任何人知识产权之意。如有侵犯请您及时与本人取得联系,万分感谢。
Tags:GIL 全局 解释 死锁 线程 队列

GIL全局解释锁

  1. GIL本质上是一个互斥锁。
  2. GIL是为了阻止同一个进程内多个进程同时执行(并行)
    • 单个进程下的多个线程无法实现并行,但能实现并发
  3. 这把锁主要是因为Cpython的内存管理不是线程安全的

    • 保证线程在执行任务时不会被垃圾回收机制回收
from threading import Thread
import time

num = 100


def task():
    global num
    num2 = num
    time.sleep(1)
    num = num2 - 1
    print(num)


for line in range(100):
    t = Thread(target=task)
    t.start()
    
# 这里的运行结果都是99, 加了IO操作,所有线程都对num进行了减值操作,由于GIL锁的存在,没有修改成功,都是99

多线程的作用

  1. 计算密集型, 有四个任务,每个任务需要10s

单核:

  • 开启进程
    • 消耗资源过大
    • 4个进程: 40s
  • 开启线程
    • 消耗资源远小于进程
    • 4个线程: 40s

多核:

  • 开启进程
    • 并行执行, 效率比较高
    • 4个进程: 10s
  • 开启线程
    • 并发执行,执行效率低
    • 4个线程: 40s
  1. IO密集型, 四个任务, 每个任务需要10s

单核:

  • 开启进程
    • 消耗资源过大
    • 4个进程: 40s
  • 开启线程
    • 消耗资源远小于进程
    • 4个线程: 40s

多核:

  • 开启进程
    • 并行执行, 效率小于多线程, 但是遇到IO会立马切换CPU的执行权限
    • 4个进程: 40s + 开启进程消耗的额外时间
  • 开启线程
    • 并发执行,执行效率高于多进程
    • 4个线程: 40s

测试计算密集型

from threading import Thread
from multiprocessing import Process
import time
import os


# 计算密集型
def work1():
    number = 0
    for line in range(100000000):
        number += 1

# IO密集型
def work2():
    time.sleep(2)


if __name__ == '__main__':
    # 测试计算密集型
    print(os.cpu_count())   # 4核cpu

    start = time.time()
    list1 = []
    for line in range(6):

        p = Process(target=work1)  # 程序执行时间8.756593704223633
        # p = Thread(target=work1)   # 程序执行时间31.78555393218994
        list1.append(p)
        p.start()
    for p in list1:
        p.join()
    end = time.time()
    print(f'程序执行时间{end - start}')

IO密集型

from threading import Thread
from multiprocessing import Process
import time
import os

# 计算密集型
def work1():
    number = 0
    for line in range(100000000):
        number += 1

# IO密集型
def work2():
    time.sleep(1)


if __name__ == '__main__':
    # 测试计算密集型
    print(os.cpu_count())   # 4核cpu

    start = time.time()
    list1 = []
    for line in range(100):

        # p = Process(target=work2)  # 程序执行时间15.354223251342773
        p = Thread(target=work2)   # 程序执行时间1.0206732749938965
        list1.append(p)
        p.start()
    for p in list1:
        p.join()
    end = time.time()
    print(f'程序执行时间{end - start}')

结论:

  • 在计算密集型的情况下, 使用多进程
  • 在IO密集型的情况下, 使用多线程
  • 高效执行多个进程, 内有多个IO密集型程序,使用多进程 + 多线程

死锁现象

指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,如无外力作用,它们都无法推进下去.此时称系统处于死锁状态

以下就是死锁:

from threading import Thread, Lock
from threading import current_thread
import time

mutex_a = Lock()
mutex_b = Lock()


class MyThread(Thread):

    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        mutex_a.acquire()
        print(f'用户{self.name}抢到锁a')
        mutex_b.acquire()
        print(f'用户{self.name}抢到锁b')
        mutex_b.release()
        print(f'用户{self.name}释放锁b')
        mutex_a.release()
        print(f'用户{self.name}释放锁a')

    def func2(self):
        mutex_b.acquire()
        print(f'用户{self.name}抢到锁b')
        time.sleep(1)
        mutex_a.acquire()
        print(f'用户{self.name}抢到锁a')
        mutex_a.release()
        print(f'用户{self.name}释放锁a')
        mutex_b.release()
        print(f'用户{self.name}释放锁b')


for line in range(10):
    t = MyThread()
    t.start()
    
    
'''
用户Thread-1抢到锁a
用户Thread-1抢到锁b
用户Thread-1释放锁b
用户Thread-1释放锁a
用户Thread-1抢到锁b
用户Thread-2抢到锁a
'''
# 一直等待

递归锁

用于解决死锁问题

RLock: 比喻成万能钥匙,可以提供给多个人使用

但是第一个使用的时候,会对该锁做一个引用计数

只有引用计数为0, 才能真正释放让一个人使用

上面的例子中用RLock代替Lock, 就不会发生死锁现象

from threading import Thread, Lock, RLock
from threading import current_thread
import time

# mutex_a = Lock()
# mutex_b = Lock()

mutex_a = mutex_b = RLock()

class MyThread(Thread):

    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        mutex_a.acquire()
        print(f'用户{self.name}抢到锁a')
        mutex_b  
		

请关注公众号获取更多资料


GIL全局解释器锁、死锁、递归锁、线程队列(一) https://www.cppentry.com/bencandy.php?fid=77&id=267932

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Python学习日记(四十二) Mysql数.. 下一篇python之模块导入方法总结

评论

验 证 码:
表  情:
内  容: