开启进程的两种方式:
#方式一:
from multiprocessing import Process
import time
def task(name):
print('%s is running' %name)
time.sleep(3)
print('%s is done' %name)
if __name__ == '__main__':
Process(target=task,kwargs={'name':'子进程1'})
p=Process(target=task,args=('子进程1',))
p.start() #仅仅只是给操作系统发送了一个信号
print('主')
*#方式二***
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print('%s is running' %self.name)
time.sleep(3)
print('%s is done' %self.name)
if __name__ == '__main__':
p=MyProcess('子进程1')
p.start()
print('主')
守护进程
from multiprocessing import Process
import time
def task(name):
print('%s is running' %name)
time.sleep(2)
p=Process(target=time.sleep,args=(3,))
p.start()
if __name__ == '__main__':
p=Process(target=task,args=('子进程1',))
p.daemon=True
p.start()
p.join()
print('主')
#互斥锁,可以对局部代码,即共享数据进行加锁,使其串性执行,而join 则是只能对全局代码实行串行
from multiprocessing import Process,Lock
import time
def task(name,mutex):
mutex.acquire()
print('%s 1' %name)
time.sleep(1)
print('%s 2' %name)
time.sleep(1)
print('%s 3' %name)
mutex.release()
if __name__ == '__main__':
mutex = Lock()
for i in range(3):
p=Process(target=task,args=('进程%s' %i,mutex))
p.start()
#抢票系统
import json
import time
def search(name):
time.sleep(1)
dic=json.load(open('db.txt','r',encoding='utf-8'))
print('<%s> 查看到剩余票数【%s】' %(name,dic['count']))
def get(name):
time.sleep(1)
dic=json.load(open('db.txt','r',encoding='utf-8'))
if dic['count'] > 0:
dic['count']-=1
time.sleep(3)
json.dump(dic,open('db.txt','w',encoding='utf-8'))
print('<%s> 购票成功' %name)
def task(name,mutex):
search(name)
mutex.acquire()
get(name)
mutex.release()
if __name__ == '__main__':
mutex=Lock()
for i in range(10):
p=Process(target=task,args=('路人%s' %i,mutex))
p.start()
#队列
q=Queue(3)
q.put('hello')
q.put({'a':1})
q.put([3,3,3,])
print(q.full())
# q.put(4)
print(q.get())
print(q.get())
print(q.get())
print(q.empty())
print(q.get())
JoinableQueue(生成者消费者模型)
import time
def producer(q):
for i in range(2):
res='包子%s' %i
time.sleep(0.5)
print('生产者生产了%s' %res)
q.put(res)
q.join()
def consumer(q):
while True:
res=q.get()
if res is None:break
time.sleep(1)
print('消费者吃了%s' % res)
q.task_done()
if __name__ == '__main__':
#容器
q=JoinableQueue()
#生产者们
p1=Process(target=producer,args=(q,))
p2=Process(target=producer,args=(q,))
p3=Process(target=producer,args=(q,))
#消费者们
c1=Process(target=consumer,args=(q,))
c2=Process(target=consumer,args=(q,))
c1.daemon=True
c2.daemon=True
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
p1.join()
p2.join()
p3.join()
print('主')
#开线程的两个方式
import random
from threading import Thread
def piao(name):
print('%s piaoing' %name)
time.sleep(random.randrange(1,5))
print('%s piao end' %name)
if __name__ == '__main__':
t1=Thread(target=piao,args=('egon',))
t1.start()
print('主线程')
import time
import random
from threading import Thread
class MyThread(Thread):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print('%s piaoing' %self.name)
time.sleep(random.randrange(1,5))
print('%s piao end' %self.name)
if __name__ == '__main__':
t1=MyThread('egon')
t1.start()
print('主')
守护线程--要等到所有线程全程结束后才结束
import time
def foo():
print(123)
time.sleep(1)
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == '__main__':
t1=Thread(target=foo)
t2=Thread(target=bar)
t1.daemon=True
t1.start()
t2.start()
print("main-------")
'''
123
456
main-------
end123
end456
'''
互斥锁,死锁,递归锁GIL-解析器锁
from threading import Thread,Lock
import time
mutexA=Lock()
mutexB=Lock()
class MyThread(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(0.1)
mutexA.acquire()
print('%s 拿到了A锁' % self.name)
mutexA.release()
mutexB.release()
if __name__ == '__main__':
for i in range(10):
t=MyThread()
t.start()
互斥锁只能acquire一次
from threading import Thread,Lock
mutexA=Lock()
mutexA.acquire()
mutexA.release()
递归锁:可以连续acquire多次,每acquire一次计数器+1,只有计数为0时,才能被抢到acquire
from threading import Thread,RLock
import time
mutexB=mutexA=RLock()
class MyThread(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(7)
mutexA.acquire()
print('%s 拿到了A锁' % self.name)
mutexA.release()
mutexB.release()
if __name__ == '__main__':
for i in range(10):
t=MyThread()
t.start()
**信号量 **互斥锁同一时间只能有一把锁,信号量同一时间可以有多把锁
import time,random
sm=Semaphore(3)
def task():
# sm.acquire()
# print('%s in' %currentThread().getName())
# sm.release()
with sm:
print('%s in' %currentThread().getName())
time.sleep(random.randint(1,3))
if __name__ == '__main__':
for i in range(10):
t=Thread(target=task)
t.start()
event事务-线程之间相互控制
# import time
#
# event=Event()
# # event.wait()
# # event.set()
#
# def student(name):
# print('学生%s 正在听课' %name)
# event.wait(2)
# print('学生%s 课间活动' %name)
#
# def teacher(name):
# print('老师%s 正在授课' %name)
# time.sleep(7)
# event.set()
#
# if __name__ == '__main__':
# stu1=Thread(target=student,args=('alex',))
# stu2=Thread(target=student,args=('wxx',))
# stu3=Thread(target=student,args=('yxx',))
# t1=Thread(target=teacher,args=('egon',))
#
# stu1.start()
# stu2.start()
# stu3.start()
# t1.start()
from threading import Thread,Event,currentThread
import time
event=Event()
def conn():
n=0
while not event.is_set():
if n == 3:
print('%s try too many times' %currentThread().getName())
return
print('%s try %s' %(currentThread().getName(),n))
event.wait(0.5)
n+=1
print('%s is connected' %currentThread().getName())
def check():
print('%s is checking' %currentThread().getName())
time.sleep(1)
event.set()
if __name__ == '__main__':
for i in range(3):
t=Thread(target=conn)
t.start()
t=Thread(target=check)
t.start()
定时器——应用于验证码的定时刷新
# from threading import Timer
#
# def task(name):
# print('hello %s' %name)
#
# t=Timer(5,task,args=('egon',))
# t.start()
from threading import Timer
import random
class Code:
def __init__(self):
self.make_cache()
def make_cache(self,interval=5):
self.cache=self.make_code()
print(self.cache)
self.t=Timer(interval,self.make_cache)
self.t.start()
def make_code(self,n=4):
res=''
for i in range(n):
s1=str(random.randint(0,9))
s2=chr(random.randint(65,90))
res+=random.choice([s1,s2])
return res
def check(self):
while True:
code=input('请输入你的验证码>>: ').strip()
if code.upper() == self.cache:
print('验证码输入正确')
self.t.cancel()
break
obj=Code()
obj.check()
线程queque
import queue
q=queue.Queue(3) #先进先出->队列
q.put('first')
q.put(2)
q.put('third')
# q.put(4)
# q.put(4,block=False) #q.put_nowait(4)
# q.put(4,block=True,timeout=3)
print(q.get())
print(q.get())
print(q.get())
# print(q.get(block=False)) #q.get_nowait()
# print(q.get_nowait())
# print(q.get(block=True,timeout=3))
q=queue.LifoQueue(3) #后进先出->堆栈
q.put('first')
q.put(2)
q.put('third')
print(q.get())
print(q.get())
print(q.get())
q=queue.PriorityQueue(3) #优先级队列
q.put((10,'one'))
q.put((40,'two'))
q.put((30,'three'))
print(q.get())
print(q.get())
print(q.get())
进程池线程池
# from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
# import os,time,random
#
# def task(name):
# print('name:%s pid:%s run' %(name,os.getpid()))
# time.sleep(random.randint(1,3))
#
#
# if __name__ == '__main__':
# # pool=ProcessPoolExecutor(4)
# pool=ThreadPoolExecutor(5)
#
# for i in range(10):
# pool.submit(task,'egon%s' %i)
#
# pool.shutdown(wait=True)
#
# print('主')
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from threading import currentThread
import os,time,random
def task():
print('name:%s pid:%s run' %(currentThread().getName(),os.getpid()))
time.sleep(random.randint(1,3))
if __name__ == '__main__':
pool=ThreadPoolExecutor(5)
for i in range(10):
pool.submit(task,)
pool.shutdown(wait=True)
print('主')
异步调用与回调机制
#提交任务的两种方式
#1、同步调用:提交完任务后,就在原地等待任务执行完毕,拿到结果,再执行下一行代码,导致程序是串行执行
#
# from concurrent.futures import ThreadPoolExecutor
# import time
# import random
#
# def la(name):
# print('%s is laing' %name)
# time.sleep(random.randint(3,5))
# res=random.randint(7,13)*'#'
# return {'name':name,'res':res}
#
# def weigh(shit):
# name=shit['name']
# size=len(shit['res'])
# print('%s 拉了 《%s》kg' %(name,size))
#
#
# if __name__ == '__main__':
# pool=ThreadPoolExecutor(13)
#
# shit1=pool.submit(la,'alex').result()
# weigh(shit1)
#
# shit2=pool.submit(la,'wupeiqi').result()
# weigh(shit2)
#
# shit3=pool.submit(la,'yuanhao').result()
# weigh(shit3)
#2、异步调用:提交完任务后,不地等待任务执行完毕,
from concurrent.futures import ThreadPoolExecutor
import time
import random
def la(name):
print('%s is laing' %name)
time.sleep(random.randint(3,5))
res=random.randint(7,13)*'#'
return {'name':name,'res':res}
def weigh(shit):
shit=shit.result()
name=shit['name']
size=len(shit['res'])
print('%s 拉了 《%s》kg' %(name,size))
if __name__ == '__main__':
pool=ThreadPoolExecutor(13)
pool.submit(la,'alex').add_done_callback(weigh)
pool.submit(la,'wupeiqi').add_done_callback(weigh)
pool.submit(la,'yuanhao').add_done_callback(weigh)
爬虫-线程池并发回调下载
from concurrent.futures import ThreadPoolExecutor
import requests
import time
def get(url):
print('GET %s' %url)
response=requests.get(url)
time.sleep(3)
return {'url':url,'content':response.text}
def parse(res):
res=res.result()
print('%s parse res is %s' %(res['url'],len(res['content'])))
if __name__ == '__main__':
urls=[
'http://www.cnblogs.com/linhaifeng',
'https://www.python.org',
'https://www.openstack.org',
]
pool=ThreadPoolExecutor(2)
for url in urls:
pool.submit(get,url).add_done_callback(parse)
#基于线程池实现通讯--控制客户端数量,达到优化运行效率
from socket import *
from concurrent.futures import ThreadPoolExecutor
def communicate(conn):
while True:
try:
data=conn.recv(1024)
if not data:break
conn.send(data.upper())
except ConnectionResetError:
break
conn.close()
def server(ip,port):
server = socket(AF_INET, SOCK_STREAM)
server.bind((ip,port))
server.listen(5)
while True:
conn, addr = server.accept()
pool.submit(communicate,conn)
server.close()
if __name__ == '__main__':
pool=ThreadPoolExecutor(2)
server('127.0.0.1', 8081)
协程是用户态的轻量级线程,协程即由用户程序自己控制调用
1.必须在单线程下实现并发
2.修改共享数据不许加锁
3.控制来回切
4.自动监控,遇到io再切(gevent)
#并发执行
import time
def producer():
g=consumer()
next(g)
for i in range(10000000):
g.send(i)
def consumer():
while True:
res=yield
start_time=time.time()
producer()
stop_time=time.time()
print(stop_time-start_time)
#串行
import time
def producer():
res=[]
for i in range(10000000):
res.append(i)
return res
def consumer(res):
pass
start_time=time.time()
res=producer()
consumer(res)
stop_time=time.time()
print(stop_time-start_time)
gevent模块监控io实现协程
from gevent import monkey;monkey.patch_all()
import gevent
import time
def eat(name):
print('%s eat 1' % name)
time.sleep(3)
print('%s eat 2' % name)
def play(name):
print('%s play 1' % name)
time.sleep(4)
print('%s play 2' % name)
g1=gevent.spawn(eat,'egon')
g2=gevent.spawn(play,'alex')
# time.sleep(5)
# g1.join()
# g2.join()
gevent.joinall([g1,g2])