day 42(锁 + )

锁:

  经典面试题

# # GIL
# # 锁
import time
from threading import Thread,Lock
def func(lock):
    global n
    # lock.acquire()
    temp = n            #在这里睡了一秒,所以程序会进入就绪状态,下面又是同步运行,但是上面可以异步运行(global n 和 temp = n) 
    # time 会让程序重新进入就绪状态,每一次执行子线程,都会改变global n,而不是真正的n
    time.sleep(0.1)
    n = temp -1
    # lock.release()

n = 100
t_lst = []
lock = Lock()   #
for i in range(100):
    t = Thread(target=func,args=(lock,))
    t.start()
    t_lst.append(t)
for t in t_lst:t.join()   #让所有线程变成同步的
print(n)
# 数据是不隔离

# from threading import Thread
#
# def func():
#     global n
#     temple = n
#     n = temple - 1
#
# n = 100
# for i in range(100):
#     t = Thread(target = func)
#     t.start()

# print(n)

互斥锁:

from threading import Thread,Lock

lock = Lock()

lock.acquire()

lock.acquire()

lock.acquire()

lock.release()

# 卡住了(阻塞了)

科学家吃面问题:

# from threading import Lock
#
# lock= Lock() # 在同一个线程中
# # 能够被一个锁的多个acquire阻塞住了
# # 这种锁就叫做互斥锁
# lock.acquire()
# lock.acquire()

# 科学家吃面问题
# 要完成一件事情 需要两个必要因素
# 要想吃到面 叉子 面
# 资源的互相抢占的问题 —— 死锁
# import time
# from threading import Thread,Lock
# def eat1(noodle_lock,fork_lock,name):
# noodle_lock.acquire()
# print('%s抢到了面'%name)
# fork_lock.acquire()
# print('%s抢到了叉子'%name)
# print('%s正在吃面'%name)
# fork_lock.release()
# print('%s归还了叉子' % name)
# noodle_lock.release()
# print('%s归还了面' % name)
#
# def eat2(noodle_lock,fork_lock,name):
# fork_lock.acquire()
# print('%s抢到了叉子' % name)
# time.sleep(0.5)
# noodle_lock.acquire()
# print('%s抢到了面'%name)
# print('%s正在吃面'%name)
# noodle_lock.release()
# print('%s归还了面' % name)
# fork_lock.release()
# print('%s归还了叉子' % name)
#
# if __name__ == '__main__':
# noodle_lock = Lock()
# fork_lock = Lock()
# Thread(target=eat1,args=(noodle_lock,fork_lock,'yuan')).start()
# Thread(target=eat2,args=(noodle_lock,fork_lock,'egon')).start()
# Thread(target=eat1,args=(noodle_lock,fork_lock,'nezha')).start()
# Thread(target=eat2,args=(noodle_lock,fork_lock,'alex')).start()

# 递归锁
# from threading import Thread,RLock
# # 在同一个线程中对同一个锁多次acquire不会产生阻塞
# # 递归锁
# def func(rlock,flag):
# rlock.acquire()
# print(flag*10)
# rlock.acquire()
# print(flag * 10)
# rlock.acquire()
# print(flag * 10)
# rlock.acquire()
# print(flag * 10)
# rlock.release()
# rlock.release()
# rlock.release()
# rlock.release()
# rlock = RLock()
# Thread(target=func,args=(rlock,'*')).start()
# Thread(target=func,args=(rlock,'-')).start()



import time
from threading import Thread,RLock
def eat1(noodle_lock,fork_lock,name):
noodle_lock.acquire()
print('%s抢到了面'%name)
fork_lock.acquire()
print('%s抢到了叉子'%name)
print('%s正在吃面'%name)
fork_lock.release()
print('%s归还了叉子' % name)
noodle_lock.release()
print('%s归还了面' % name)

def eat2(noodle_lock,fork_lock,name):
fork_lock.acquire()
print('%s抢到了叉子' % name)
time.sleep(0.5)
noodle_lock.acquire()
print('%s抢到了面'%name)
print('%s正在吃面'%name)
noodle_lock.release()
print('%s归还了面' % name)
fork_lock.release()
print('%s归还了叉子' % name)

if __name__ == '__main__':
fork_lock = noodle_lock = RLock()
Thread(target=eat1,args=(noodle_lock,fork_lock,'yuan')).start()
Thread(target=eat2,args=(noodle_lock,fork_lock,'egon')).start()
Thread(target=eat1,args=(noodle_lock,fork_lock,'nezha')).start()
Thread(target=eat2,args=(noodle_lock,fork_lock,'alex')).start()

# 有超过一个资源需要锁的时候 —— 递归锁
# 递归锁的应用场景
# 互斥锁和递归锁的区别



import time
import random
from threading import Event,Thread

# wait()
# set clear isset

# 连接数据库
def connect_db(e):
count = 1
while count < 4:      #第一次进入默认是False
print('尝试第%s次检测连接'%count)
e.wait(0.5)
# 如果不传参数会一直等到事件为True为止
# 如果传参数 传一个时间参数
count += 1
if e.is_set():
print('连接成功')
break
else:
print('连接失败')

def check_conn(e):
'''检测数据库是否可以连接'''
time.sleep(random.randint(1,2))
e.set()                        此题:如果小于1.5 会把状态False 改为 True ,否则会执行else:结束程序

e = Event()
Thread(target=check_conn,args=(e,)).start()
Thread(target=connect_db,args=(e,)).start()

# 你要做一件事情 是有前提的
# 你就先去处理前提的问题 —— 前提处理好了 把状态设置成True
# 来控制即将要做的事情可以开始

条件和定时器:

 from threading import Condition,Thread
# # acquire release
# # notify -- wait的行为
# # 10线程 wait
# # notify(1)
# def func(i,con):
# con.acquire()
# con.wait()
# print(i*'*')
# con.release()
#
# con = Condition()
# for i in range(10):
# Thread(target=func,args=(i,con)).start()
# while True:
# n = int(input('>>>'))
# con.acquire()
# con.notify()
# con.release()
#
# con.acquire()
# con.notify_all()
# con.release()

# semaphore 允许统一是个n个线程执行这段代码
# event 有一个内部的事件来控制wait的行为
#控制的是所有的线程
# condition 有一个内部的条件来控制wait的行为
#可以逐个或者分批次的控制线程的走向

from threading import Timer
def func():
print('*'*20)

t = Timer(5,func) # 要开启一个线程,等到5秒钟之后才开启并且执行
t.start()
print('-'*10)
print('^'*10)




队列:

import queue

q = queue.LifoQueue()
q = queue.Queue()
q.put('first')
q.put((1,2))
q.put([1,2])
q.put({'k':'v'})
q.put(lambda :1)
print(q.get())
print(q.get())
print(q.get())
print(q.get())

q = queue.PriorityQueue()
q.put((1,'a')) #数字越小优先级越高
q.put((20,'z'))
q.put((20,'b'))
print(q.get())
print(q.get())
print(q.get())




线程池:

# import time
# from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
# def func(i):
# print(i*'*')
# time.sleep(1)
# return i**2
#
# def callb(arg):
# print(arg.result()*'-')
#
# if __name__ == '__main__':
# # thread_pool = ThreadPoolExecutor(5)
# thread_pool = ThreadPoolExecutor(5)
# # ret_lst = []
# for i in range(10):
# thread_pool.submit(func,i).add_done_callback(callb) # 相当于apply_async
# # ret = thread_pool.submit(func,i).add_done_callback(callable) # 相当于apply_async
# # ret_lst.append(ret)
# thread_pool.shutdown() # close+join
# # for ret in ret_lst:
# # print(ret.result())
# print('wahaha')
# # 回调函数

# 进程池
# 线程池


# 当内存不需要共享,且高计算的时候 用进程
# 当内存需要共享,且高IO的时候 用线程
# 当并发很大的时候
# 多进程 : 多个任务 —— 进程池 :cpu个数、cpu个数+1
# 多线程 :多个任务 —— 线程池 :cpu个数*5
# 4C : 4个、5个进程 —— 20条线程/进程 : 80-100个任务
# 50000

# import time
# from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
#
# def fun(i):
# print(i*'*')
# time.sleep(1)
# return i**2
#
# def callc(args):
# print(args.result()*'-')
#
#
# thread_pool = ThreadPoolExecutor(5)
# for i in range(10):
# ret = thread_pool.submit(fun,i).add_done_callback(callc)
# # thread_pool.map(fun,range(10))
# thread_pool.shutdown()
# print('wahh')




import time
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

def fun(i):
print('*'*i)
time.sleep(1)
return i**2

def callc(args):
print(args.result() * '-')

thread_pool = ThreadPoolExecutor(5)
for i in range(10):
ret = thread_pool.submit(fun,i).add_done_callback(callc)

thread_pool.shutdown()

print('主线程')














原文地址:https://www.cnblogs.com/zsdbk/p/9048187.html