python学习第32天
Posted 打酱油的阿超
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python学习第32天相关的知识,希望对你有一定的参考价值。
一. Manager
进程之间的共享数据(列表list 或者 字典dict等)
from multiprocessing import Process,Manager,Lock
def work(data,lock):
# 1.正常写法
"""
lock.acquire()
# data["count"] -= 1
data[0] += 1
lock.release()
"""
# 2.使用with 语法简化上锁解锁操作
with lock:
data[0] += 1
if __name__ == "__main__":
m = Manager()
# 创建一个共享的字典
data = m.dict( {"count":20000} )
# 创建一个共享的列表
data = m.list([1,2,3])
# print(data)
lst = []
lock = Lock()
for i in range(100):
p = Process(target=work,args=(data,lock))
p.start()
lst.append(p)
# 确保所有的进程执行完毕,然后在向下运行,打印数据,否则报错;
for i in lst:
i.join()
print(data) # [101, 2, 3]
二. 线程
#进程是资源分配的最小单位
#线程是计算机中调度的最小单位
#线程的缘起
资源分配需要分配内存空间,分配cpu:
分配的内存空间存放着临时要处理的数据等,比如要执行的代码,数据
而这些内存空间是有限的,不能无限分配
目前配置高的主机,5万个并发已是上限.线程概念应用而生.
#线程的特点
线程是比较轻量级,能干更多的活,一个进程中的所有线程资源是共享的.
一个进程至少有一个线程在工作
1 . 一份进程资源中可以包含多个线程
from threading import Thread
from multiprocessing import Process
import os
"""
def func(num):
print(‘当前线程{},所归属的进程id号{}‘.format(os.getpid(),num))
for i in range(10):
# 异步创建10个子线程
t = Thread(target=func,args=(i,))
t.start()
# 主线程执行任务
print(os.getpid())
2 . 并发多线程和多进程, 多线程的速度更快,谨慎选择创建进程的数量
import time
def func(num):
print(‘当前线程{},所归属的进程id号{}‘.format(os.getpid(),num))
if __name__==‘__main__‘:
"""
#记录开始时间
starttime=time.time()
lst=[]
for i in range(1000):
t=Thread(target=func,args=(i,))
t.start()
lst.append(t)
# 等到所有子线程执行完毕
for i in lst:
i.join()
# 记录结束时间
endtime=time.time()
print("多线程执行时间:",endtime-starttime)
"""
"""
#记录开始时间
starttime=time.time()
lst=[]
for i in range(1000):
p=Process(target=func,args=(i,))
p.start()
lst.append(p)
# 等到所有子线程执行完毕
for i in lst:
i.join()
# 记录结束时间
endtime=time.time()
print("多进程执行时间:",endtime-starttime)
3 .多线程共享同一份进程资源
num =1000
def func():
global num
num -=1
for i in range(1000):
t=Thread(target=func)
t.start()
print(num)
4 . 用自定义类的方法创建线程
一定要继承父类Thread
手动调用父类的构造方法
class MyThread(Thread):
def __init__(self,name):
# 手动调用父类的构造方法
super().__init__()
self.name = name
def run(self):
time.sleep(1)
print("当前进程正在执行runing ... " , self.name)
if __name__ == "__main__":
t = MyThread("机器今天会再次爆炸么?")
t.start()
print("主线程执行结束 ... ")
5 . 线程相关的函数
线程.is_alive() 检测线程是否仍然存在
线程.setName() 设置线程名字
线程.getName() 获取线程名字
1.currentThread().ident 查看线程id号
2.enumerate() 返回目前正在运行的线程列表
3.activeCount() 返回目前正在运行的线程数量
def func():
time.sleep(1)
if __name__ == "__main__":
t = Thread(target=func)
# print(t)
t.start()
# print(t , type(t))
print(t.is_alive()) # False
print(t.getName())
t.setName("xboyww")
print(t.getName())
currentThread().ident 查看线程id号
def func():
print("子线程id",currentThread().ident , os.getpid())
if __name__ == "__main__":
Thread(target=func).start()
print("主线程id",currentThread().ident , os.getpid())
enumerate() 返回目前正在运行的线程列表
acctiveCount() 返回目前正在运行的线程数量
from threading import enumerate
from threading import activeCount # (了解)
def func():
print("子线程id",currentThread().ident , os.getpid())
time.sleep(0.5)
if __name__ == "__main__":
for i in range(10):
Thread(target=func).start()
lst = enumerate()
# 子线程10 + 主线程1个 = 11
# print(lst ,len(lst))
# 3.activeCount() 返回目前正在运行的线程数量
print( activeCount() )
6 .守护线程
等待所有线程全部执行完毕之后,在自己终止,守护的是所有线程
线程名.setDaemon(True)
from threading import Thread
import time
def func1():
while True:
time.sleep(0.5)
print("我是func1")
def func2():
print("我是func2 start ... ")
time.sleep(3)
print("我是func2 end ... ")
t1 = Thread(target=func1)
t2 = Thread(target=func2)
# 在start调用之前,设置守护线程
t1.setDaemon(True)
t1.start()
t2.start()
print("主线程执行结束 ... ")
7 . 用 Lock 保证数据安全
from threading import Lock,Thread
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 自动完成上锁+解锁
with lock:
for i in range(1000000):
# 方法二
n += 1
# func1()
# func2()
# print(n)
if __name__ == "__main__":
lst = []
lock = Lock()
time1 = time.time()
for i in range(10):
t1 = Thread(target=func1,args=(lock,))
t2 = Thread(target=func2,args=(lock,))
t1.start()
t2.start()
lst.append(t1)
lst.append(t2)
# 等待所有的子线程执行结束之后, 在打印数据
for i in lst:
i.join()
time2 = time.time()
print("主线程执行结束..." , n ,time2 - time1)
8 . 信号量 Semaphore(线程)
from threading import Semaphore,Thread
import time
def func(i,sm):
with sm:
print(i)
time.sleep(3)
if __name__ == "__main__":
sm = Semaphore(5)
for i in range(20):
Thread(target=func,args=(i,sm)).start()
"""
总结:
在创建线程的时候是异步创建
在执行任务的时候,因为Semaphore加了锁,所以线程之间变成了同步
"""
以上是关于python学习第32天的主要内容,如果未能解决你的问题,请参考以下文章