lock.acquire()# 上锁
lock.release()# 解锁
同一时间允许一个进程上一把锁 就是Lock
加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲速度却保证了数据安全。
同一时间允许多个进程上多把锁 就是[信号量Semaphore]
信号量是锁的变形: 实际实现是 计数器 + 锁,同时允许多个进程上锁
互斥锁Lock : 互斥锁就是进程的互相排斥,谁先抢到资源,谁就上锁改资源内容,为了保证数据的同步性
注意:多个锁一起上,不开锁,会造成死锁.上锁和解锁是一对.
def func(i):
print( "当前进程号:{} , 参数是{} ".format(os.getpid() , i) )
if __name__ == "__main__":
lst = []
startime = time.time()
for i in range(10000):
p = Process(target=func,args=(i,))
p.start()
lst.append(p)
# print(lst)
for i in lst:
i.join()
endtime = time.time()
print("运行的时间是{}".format(endtime - startime) ) # 运行的时间是101.68004035949707
# ### Manager ( list 列表 , dict 字典 ) 进程之间共享数据
from multiprocessing import Process , Manager ,Lock
def mywork(data,lock):
# 共享字典
"""
lock.acquire()
data["count"] -= 10
lock.release()
"""
# 共享列表
data[0] += 1
if __name__ == "__main__":
lst = []
m = Manager()
lock = Lock()
# 多进程中的共享字典
# data = m.dict( {"count":5000} )
# print(data , type(data) )
# 多进程中的共享列表
data = m.list( [100,200,300] )
# print(data , type(data) )
""""""
# 进程数超过1000,处理该数据,死机(谨慎操作)
for i in range(10):
p = Process(target=mywork,args=(data,lock))
p.start()
lst.append(p)
# 必须等待子进程所有计算完毕之后,再去打印该字典,否则报错;
for i in lst:
i.join()
print(data)
from multiprocessing import Process, Queue
def test1(q):
print(q.get())
# print(q)
# q.put(124)
# q.put(test)
q.put(123)
return 123
# tt = test()
def test():
return 123
if __name__ == '__main__':
q = Queue()
p1 = Process(target=test1, args=(q,))
p1.start()
q.put(test)
p1.join()
print(q.get())
# q.get()
def func(i):
print( "当前进程号:{} , 参数是{} ".format(os.getpid() , i) )
if __name__ == "__main__":
lst = []
startime = time.time()
for i in range(10000):
t = Thread(target=func,args=(i,))
t.start()
lst.append(t)
# print(lst)
for i in lst:
i.join()
endtime = time.time()
print("运行的时间是{}".format(endtime - startime) ) # 运行的时间是1.8805944919586182
from threading import Thread, Lock, Semaphore
import time
n = 0
def func1(lock):
global n
lock.acquire()
for i in range(1000000):
n += 1
lock.release()
def func2(lock):
global n
with lock:
for i in range(1000000):
n -= 1
if __name__ == '__main__':
lock = Lock()
lis = []
t1 = Thread(target=func1, args=(lock, ))
t1.start()
t2 = Thread(target=func2, args=(lock, ))
t2.start()
lis.append(t1)
lis.append(t2)
for i in lis:
i.join()
print('主进程结束,打印n:{0}'.format(n))
=====》
结果: 是0 ,不加锁会出错
from concurrent.futures import ProcessPoolExecutor , ThreadPoolExecutor
"""多条进程提前开辟,可触发多cpu的并行效果"""
# (1) 进程池 ProcessPoolExecutor
def func(i, j):
# print(i)
time.sleep(random.uniform(0.1,0.8))
print(" 任务执行中 ... start ... 进程号{}".format(os.getpid()) , i )
print(" 任务执行中 ... end ... 进程号{}".format(os.getpid()))
return i
if __name__ == "__main__":
lst = []
# (1) 创建进程池对象
"""4核电脑,进程默认是4, 线程是4*5"""
p = ProcessPoolExecutor()
# (2) 异步提交任务
"""submit(任务,参数1,参数2 ... )"""
"""默认如果一个进程短时间内可以完成更多的任务,进程池就不会使用更多的进程来辅助完成 , 可以节省系统资源的损耗;"""
for i in range(10):
obj = p.submit( func , i , 1)
# print(obj)
# print(obj.result()) 不要写在这,导致程序同步,内部有阻塞
lst.append(obj)
# (3) 获取当前任务的返回值
for i in lst:
print(i.result(),">===获取返回值===?")
# (4) shutdown 等待所有进程池里的进程执行完毕之后,在放行
p.shutdown()
print("进程池结束 ... ")
# (3) 线程池 map
from threading import currentThread as ct
from collections import Iterator,Iterable
def func(i):
time.sleep(random.uniform(0.1,0.7))
print("thread ... 线程号{}".format(ct().ident),i)
return "*" * i
if __name__ == "__main__":
t = ThreadPoolExecutor()
it = t.map(func,range(100))
# 返回的数据是迭代器
print(isinstance(it,Iterator))
# 协调子父线程,等待线程池中所有线程执行完毕之后,在放行;
t.shutdown()
# 获取迭代器里面的返回值
for i in it:
print(i)
协程也叫纤程: 协程是线程的一种实现方式.
协程的实现
一个线程可以由多个协程来实现,协程之间不会产生数据安全问题
协程模块:gevent
“”“
#(1)apawm(函数,参数1,参数2,参数.…)启动协程
#(2)join阻塞,直到某个协程在任务执行完毕之后在放行
#(3)joinal1等待所有协程任务执行完毕之后放行;g1.join()g2.join()<=>gevent.joinall([gl,g2..])
#(4)value获取协程任务中的返回值gl.value g2.value rttrn from gevent import monkey;monkey.patch_all()
”“”
import gevent
import time
def eat():
print("eat1开始吃…")
time.sleep(1)
print("eat2继续吃..")
return "吃完了"
def play():
print("play1开始玩…")
time.sleep(1)
print("play2继续玩…")
return "玩完了"
# 创建协程对象g1
gl = gevent.spawn(eat)
# 创建协程对象g2
g2 = gevent.spawn(play)
# 等待所有协程任务执行完毕之后放行
gevent.joinall([gl, g2])
print("主线程执行结束.…")
# 获取协程任务中的返回值
print(g1.value)
print(g2.value)