锁,threading local,以及生产者和消费者模型

1.锁:Lock(一次放行一个)

  线程安全,多线程操作时,内部会让所有的线程排队处理。

  线程不安全:+人=>排队处理

  以后锁代码块

v=[]
lock=threading.Lock()#声明锁
def func(arg):
    lock.acquire()#上锁
    v.append(arg)
    time.sleep(0.1)
    m=v[-1]
    print(arg,m)
    lock.release()#解锁
for i in range(10):
    t=threading.Thread(target=func,args=(i,))
    t.start()
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9

2.锁:Rlock(一次放一个)

  支持递归锁,锁多次

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()
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9

3.一次放多个:BoundedSemaphore

  threading.BoundedSemaphore(指定一次放几个就放几个),信号量

import time
import threading
lock=threading.BoundedSemaphore(5)#指定几个就每次执行几个线程
def func(arg):
    lock.acquire()
    print(arg)
    time.sleep(3)
    lock.release()
for i in range(20):
    t=threading.Thread(target=func,args=(i,))
    t.start()

4.条件锁Condition(一次放指定个数,用户输入几个就放几个)******

方法一:
import
time import threading lock=threading.Condition()#声明放的方式 def func(arg): lock.acquire() lock.wait()#上锁 print(arg) time.sleep(2) lock.release() for i in range(20): t=threading.Thread(target=func,args=(i,)) t.start() while 1: user=int(input(">>>")) lock.acquire() lock.notify(user)#重点操作 lock.release()
方法二:
def xxx():
input('>>>')
return True
def func(arg):
lock.wait_for(xxx)
print(arg)
time.sleep(1)
for i in range(10):
t=threading.Thread(target=func,args=(i,))
t.start()

5.Event(一次放所有)

import threading
import time
lock=threading.Event()声明一次放掉全部的线程
def func(arg):
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()绿灯

 

总结:

  线程安全:列表和字典是线程安全的,队列。

  为什么要加锁?

  非线程安全的可以人为加锁,控制一段代码!

6.threading.local

作用:

  内部自动为每个线程维护一个空间(字典),用于当前存取属于自己的值,保证线程之间的数据隔离。

应用:
import
threading import time v=threading.local() def func(arg): v.phone=arg time.sleep(2) print(v.phone,arg) for i in range(10): t=threading.Thread(target=func,args=(i,)) t.start()
原理:
import threading
import time
v=threading.local()
def func(arg):
v.phone=arg
time.sleep(2)
print(v.phone,arg)
for i in range(10):
t=threading.Thread(target=func,args=(i,))
t.start()

7.线程池:控制最多开指定的线程

import threading
from concurrent.futures import ThreadPoolExecutor
import time
def func(a1,a2):
    time.sleep(2)
    print(a1,a2)
pool = ThreadPoolExecutor(5)#创建线程池,最多5个线程
for i in range(20):
    #去线程池中申请一个线程,让线程执行该函数
    pool.submit(func,i,20)

8.生产者消费者模型

import threading
import queue
import time
q=queue.Queue()#线程安全
def func(id):
    """
    生产者
    :param id:
    :return:
    """
    while 1:
        time.sleep(2)
        q.put('包子')
        print('厨子%s,做了一个包子' %id)
for i in range(1,5):
    t=threading.Thread(target=func,args=(i,))
    t.start()
def usera(id):
    """
    消费者
    :param id: 
    :return: 
    """
    while 1:
        q.get()
        print('第%s个顾客吃了一个包子' %id)
for i in range(1,8):
    t=threading.Thread(target=usera,args=(i,))
    t.start()

队列:先进先出

扩展:

  栈:后进先出

内容补充:

线程池在python2中是没有的,线程不能太多,会造成线程的上下切换,影响效率

进程和线程的区别?

1.进程是CPU资源分配的最小单元

线程是CPU计算的最小单元

2.一个进程中可以有多个线程,

3.对于python来说,进程线程和其他语言有差异,是由gill锁造成的,gill锁保证一个进程中,同一时刻只能有一个线程能被CPU调度

进程是进行数据隔离

线程是CPU工作的最小单元,共享进程中的所有资源,每个线程分担一些任务,最终执行

原文地址:https://www.cnblogs.com/wqzn/p/9628535.html