一、线程组件
1、信号量:同一时间只能有n个线程被执行
from threading import Semaphore,Thread
import time
def func(sem,a,b):
sem.acquire()
time.sleep(1)
print(a + b)
sem.release()
sem = Semaphore(4)
for i in range(10):
t = Thread(target=func,args=(sem,i,i+2))
t.start()
输出结果:(四个四个输出)
4
2
8
6
10
12
14
16
18
20
2、线程组件(事件)
(1)`False`状态 `wait()`阻塞
`Ture`状态 `wait()`非阻塞
(2)clear可改变状态为False,set设置状态为True
3、连接数据库,以及检测数据库的可连接情况
数据库-->文件夹,文件夹里有好多excel表格
数据库好处:(1),能够更方便的对数据进行增删改查
(2),安全访问的机制
4、例:起两个线程:
第一个线程:连接数据库,等待信号告诉我们之间网络是通的
第二个线程:检测数据库之间的网络是否连通,0-2秒之间若为通,将事件状态设置为Ture
import time
import random
from threading import Thread,Event
def connect_db(e):
count = 0
while count < 3:
e.wait(1) #状态为False的时候,我只等待一秒
if e.is_set() == True:
print('连接数据库....')
break
else:
count += 1 #三次连接失败检测
print('第%s连接失败。。。。'%count)
else:
raise TimeoutError('数据库连接超时')#主动抛异常,自己写异常
def check_web(e):
time.sleep(random.randint(0,3))
e.set()
e = Event()
t1 = Thread(target=connect_db,args=(e,))
t2 = Thread(target=check_web,args=(e,))
t1.start()
t2.start()
输出结果:
第1连接失败。。。。
连接数据库…
3、条件(锁,acquire,release)
(1)一个条件被创建之初默认有一个False状态
(2)False状态会影响wait一直处于等待状态
(3)notify(int数据类型) 造钥匙,造的钥匙是一次性的,不再归还
from threading import Thread,Condition
def func(con,i):
con.acquire()
con.wait() #等钥匙
print('在第%s个函数里'%i)
con.release()
con = Condition()
for i in range(10):
Thread(target=func,args=(con,i)).start()
while True:
num = int(input('>>>'))
con.acquire()
con.notify(num)#是一个造钥匙的,可造num个钥匙
con.release()
输出结果:
‘>>>3
’>>>在第1个函数里
在第2个函数里
在第0个函数里
4、定时器
from threading import Timer
def func():
print('时间同步')
Timer(2,func).start()#定制一个定时开启线程
from threading import Timer
import time
def func():
print('时间同步')
while True:
Timer(2,func).start()#定制一个定时开启线程
time.sleep(2)
5、 队列
import queue
q = queue.Queue()#先进先出
q.put()
q.put_nowait()# 队列满直接抛异常
q.get()
q.get_nowait()#队列没数据直接抛异常
import queue
q = queue.LifoQueue()#栈(先进后出) (数据类型)
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())
输出结果:
3
2
1
import queue
q = queue.PriorityQueue()#优先级队列(数越小优先级越高)
q.put((2,'a'))
q.put((1,'b'))
q.put((3,'c'))
q.put((1,'d'))#若所给优先级一样,按照ASII码排
print(q.get())
print(q.get())
print(q.get())
print(q.get())
输出结果:
(1, ‘b’)
(1, ‘d’)
(2, ‘a’)
(3, ‘c’)
二、线程池
1、
import time
from concurrent.futures import ThreadPoolExecutor
def func(n):
time.sleep(2)
print(n)
return n**2
tpool = ThreadPoolExecutor(max_workers=5)#默认不要超过cpu个数*5
t_list = []
for i in range(10):
t = tpool.submit(func,i)
t_list.append(t)
tpool.shutdown()#相当于close+join
print('主线程')
for t in t_list:print('*',t.result())
2、map
import time
from concurrent.futures import ThreadPoolExecutor
def func(n):
time.sleep(2)
print(n)
return n**2
tpool = ThreadPoolExecutor(max_workers=5)#默认不要超过cpu个数*5
tpool.map(func,range(10))#拿不到返回值
3、ThreadPoolExecutor
import time
from concurrent.futures import ThreadPoolExecutor
def func(n):
time.sleep(2)
print(n)
return n**2
def call_back(m):
print('结果是:%s'%m.result())
tpool = ThreadPoolExecutor(max_workers=5)#默认不要超过cpu个数*5
t_list = []
for i in range(10):
tpool.submit(func,i).add_done_callback(call_back)
4、
sever端:
import socket
from threading import Thread
def chat(conn):
conn.send(b'hello')
msg = conn.recv(1024).decode('utf-8')
print(msg)
conn.close()
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen(5)
while True:
conn,addr = sk.accept()
t = Thread(target=chat,args=(conn,)).start()
sk.close()
client端:
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
msg = sk.recv(1024).decode('utf-8')
print(msg)
inp = input('>>>').encode('utf-8')
sk.send(inp)