python GIL锁

python GIL锁:

  - python 内置的一个全局解释器锁,锁的作用就是保证同一时刻,一个进程中只有一个线程可以被CPU调度.

  - 有这把锁的原因是因为python语言的创始人在开发这门语言时,为了快速把语言开发出来,如果加上GIL锁(C语言加锁),切换时按照100条字节指令来进行线程间的切换.

 

进程与线程的区别:

  - 线程,CPU工作的最小单元.

  - 进程,为线程提供一个资源共享的空间.

  (ps:一个进程中默认有一个主线程)

在python中的进程和线程的使用准则:

  - 计算密集型: 多进程

  - IO密集型: 多线程

 

线程:

锁Lock:

 

import threading
import time

v = []
lock = threading.Lock()

def func(arg):
    lock.acquire()
    v.append(arg)
    time.sleep(0.01)
    m = v[-1]
    print(arg,m)
    lock.release()


for i in range(10):
    t =threading.Thread(target=func,args=(i,))
    t.start()
Lock

 

锁RLock:

import threading
import time

v = []
lock = threading.RLock()
def func(arg):
    lock.acquire()
    lock.acquire()

    v.append(arg)
    time.sleep(0.01)
    m = v[-1]
    print(arg,m)

    lock.release()
    lock.release()


for i in range(10):
    t =threading.Thread(target=func,args=(i,))
    t.start()
RLock

锁semaphore:

import time
import threading

lock = threading.BoundedSemaphore(3)
def func(arg):
    lock.acquire()
    print(arg)
    time.sleep(1)
    lock.release()


for i in range(20):
    t =threading.Thread(target=func,args=(i,))
    t.start()
Semaphore

锁Condition:

import time
import threading

lock = threading.Condition()

# ############## 方式一 ##############

def func(arg):
    print('线程进来了')
    lock.acquire()
    lock.wait() # 加锁

    print(arg)
    time.sleep(1)

    lock.release()


for i in range(10):
    t =threading.Thread(target=func,args=(i,))
    t.start()

while True:
    inp = int(input('>>>'))

    lock.acquire()
    lock.notify(inp)
    lock.release()
Condition

锁Event:

import time
import threading

lock = threading.Event()


def func(arg):
    print('线程来了')
    lock.wait() # 加锁:红灯
    print(arg)


for i in range(10):
    t =threading.Thread(target=func,args=(i,))
    t.start()

input(">>>>")
lock.set() # 绿灯


lock.clear() # 再次变红灯

for i in range(10):
    t =threading.Thread(target=func,args=(i,))
    t.start()

input(">>>>")
lock.set()
Event

锁local:

import time
import threading

v = threading.local()

def func(arg):
    # 内部会为当前线程创建一个空间用于存储:phone=自己的值
    v.phone = arg
    time.sleep(2)
    print(v.phone,arg) # 去当前线程自己空间取值

for i in range(10):
    t =threading.Thread(target=func,args=(i,))
    t.start()
local

 

 线程池:

from concurrent.futures import ThreadPoolExecutor
import time

def task(a1,a2):
    time.sleep(2)
    print(a1,a2)

# 创建了一个线程池(最多5个线程)
pool = ThreadPoolExecutor(5)

for i in range(40):
    # 去线程池中申请一个线程,让线程执行task函数。
    pool.submit(task,i,8)
线程池

 

进程池:

import time
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

def task(arg):
    time.sleep(2)
    print(arg)

if __name__ == '__main__':

    pool = ProcessPoolExecutor(5)
    for i in range(10):
        pool.submit(task,i)
进程池

 

 

生产者消费者模型:

 

import time
import queue
import threading
q = queue.Queue() # 线程安全

def producer(id):
    """
    生产者
    :return:
    """
    while True:
        time.sleep(2)
        q.put('包子')
        print('厨师%s 生产了一个包子' %id )

for i in range(1,4):
    t = threading.Thread(target=producer,args=(i,))
    t.start()


def consumer(id):
    """
    消费者
    :return:
    """
    while True:
        time.sleep(1)
        v1 = q.get()
        print('顾客 %s 吃了一个包子' % id)

for i in range(1,3):
    t = threading.Thread(target=consumer,args=(i,))
    t.start()

 

posted @ 2018-09-11 15:25  氐惆  阅读(245)  评论(0编辑  收藏  举报