day 31

一.GIL全局解释器锁

'''
1. 什么是GIL全局解释器锁
    GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程
    必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行
    但是可以实现并发

    在Cpython解释器下,如果想实现并行可以开启多个进程

2. 为何要有GIL
    因为Cpython解释器的垃圾回收机制不是线程安全的

3. 如何用GIL
    有了GIL,应该如何处理并发
4.总结:
    1.io密集型:用多线程(开发中大部分用多线程)
    2.计算密集型:用多进程
    

'''
# from threading import Thread
# import time
#
# def task(name):
#     print('%s is running' %name)
#     time.sleep(2)
#
# if __name__ == '__main__':
#     t1=Thread(target=task,args=('线程1',))
#     t2=Thread(target=task,args=('线程1',))
#     t3=Thread(target=task,args=('线程1',))
#     t1.start()
#     t2.start()
#     t3.start()

# 计算密集型:应该使用多进程
# from multiprocessing import Process
# from threading import Thread
# import os,time
#
# def work():
#     res=0
#     for i in range(100000000):
#         res*=i
#
# if __name__ == '__main__':
#     l=[]
#     print(os.cpu_count())
#     start=time.time()
#     for i in range(6):
#         # p=Process(target=work)
#         p=Thread(target=work)
#         l.append(p)
#         p.start()
#     for p in l:
#         p.join()
#     stop=time.time()
#     print('run time is %s' %(stop-start)) #4.271663427352905

# IO密集型: 应该开启多线程
from multiprocessing import Process
from threading import Thread
import threading
import os,time
def work():
    time.sleep(2)

if __name__ == '__main__':
    l=[]
    start=time.time()
    for i in range(300):
        # p=Process(target=work) #2.225289821624756
        p=Thread(target=work) #2.002105951309204
        l.append(p)
        p.start()
    for p in l:
        p.join()
    stop=time.time()
    print('run time is %s' %(stop-start))

二.GIL vs 自定义互斥锁:

from threading import Thread, Lock
import time

# n = 100
# muete = Lock()
#
#
# def task():
#     global n
#     with muete:
#         temp = n
#         time.sleep(0.1)
#         n = temp - 1
#
#
# if __name__ == '__main__':
#     li=[]
#     for i in range(100):
#         t = Thread(target=task)
#         li.append(t)
#         t.start()
#
#     for t in li:
#         t.join()
#     print(n)

# def foo1():
#     print("1")
#     time.sleep(1)
#     print("睡了一秒")
#
# def foo2():
#     time.sleep(2)
#     print("222")
#
# if __name__ == '__main__':
#     t1=Thread(target=foo1)
#     t2=Thread(target=foo2)
#     t1.start()
#     t2.start()
#     t1.join()
#     print("主")

三 .死锁现象与递归锁

"""
死锁现象:指的是互相拿了对方需要的钥匙,但都不放手,导致了程序的堵塞
递归锁:就是为了解决死锁现象:RLock

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

mutexA=Lock()
mutexB=Lock()
# mutexB=mutexA=RLock()


class Mythead(Thread):
    def run(self):
        self.f1()
        self.f2()

    def f1(self):
        mutexA.acquire()
        print('%s 抢到A锁' %self.name)
        mutexB.acquire()
        print('%s 抢到B锁' %self.name)
        mutexB.release()
        mutexA.release()

    def f2(self):
        mutexB.acquire()
        print('%s 抢到了B锁' %self.name)
        time.sleep(2)
        mutexA.acquire()
        print('%s 抢到了A锁' %self.name)
        mutexA.release()
        mutexB.release()

if __name__ == '__main__':
    for i in range(100):
        t=Mythead()
        t.start()

四.信号量

"""
信号量:semaphore 控制统一进程下的并发的线程的个数

"""
from threading import Thread, Semaphore
import time, random

sm = Semaphore(5)





def task(name):
    sm.acquire()
    print('%s 正在上厕所' % name)
    time.sleep(random.randint(1, 3))
    sm.release()


if __name__ == '__main__':
    for i in range(20):
        t = Thread(target=task, args=('路人%s' % i,))
        t.start()

五.Event 事件

from threading import Thread, Event
import time

event = Event()


def light():
    print('红灯正亮着')
    time.sleep(3)
    event.set()  # 绿灯亮


def car(name):
    print('车%s正在等绿灯' % name)
    event.wait()  # 等灯绿
    print('车%s通行' % name)


if __name__ == '__main__':
    # 红绿灯
    t1 = Thread(target=light)
    t1.start()
    #
    for i in range(10):
        t = Thread(target=car, args=(i,))
        t.start()

六.线程的queue

import queue

# queue.Queue() #先进先出
# q=queue.Queue(3)
# q.put(1)
# q.put(2)
# q.put(3)
# print(q.get())
# print(q.get())
# print(q.get())

# queue.LifoQueue() #后进先出->堆栈
# q=queue.LifoQueue(3)
# q.put(1)
# q.put(2)
# q.put(3)
# print(q.get())
# print(q.get())
# print(q.get())
# queue.PriorityQueue() #优先级
# q=queue.PriorityQueue(3) #优先级,优先级用数字表示,数字越小优先级越高
# q.put((10,'a'))
# q.put((-1,'b'))
# q.put((100,'c'))
# print(q.get())
# print(q.get())
# print(q.get())
原文地址:https://www.cnblogs.com/jxl123/p/9605112.html