OK通过上面两篇的内容,对进程有了一个初步的认识 进程 就是一个方法,就跟面相对象,函数一样,都是python中的方法,为了能够
让自己程序更有效率. 上两篇就是告诉大家,进程的一个样子,怎样的一个书写格式, 大家只要记住格式是什么,会用就可以了, 进程的那些概念的东西,
大家可以没事上百度,了解一下就可以了.
话不多说,接下来就是 进程 的一些使用方法
import os #这次我们倒入一个os模块 待会查看一下进程id
from multiprocessing import Process
def f1():
print('子进程的pid',os.getpid()) #os.getpid()是获取进程id 的
print('子进程的父进程的pid',os.getppid()) #os.getppid() 是获取在子进程中父进程的进程id
#仔细看这两个方法不一样
print('aaa')
def f2():
print('bbb')
if __name__ == '__main__':
p1 = Process(target=f1,name='宝宝1')
p2 = Process(target=f2,)
p1.start()
p2.start()
print(p1.name) #查看进程传参的属性 也就是宝宝1 没啥意思这个功能
print('子进程的pid',p1.pid) # 获取子进程进程id
print('父进程的id',os.getpid()) #获取父进程的id
最后打印完结果,你就会发现,所有的父进程是同一个id,,,所有子进程是同一个id, 这就说明子进程跟父进程是两个id,不是一起的..稍微记住
from multiprocessing import Process
def f1():
print('子进程1号')
if __name__ == '__main__':
p = Process(target=f1,)
p.start()
print(p.is_alive()) #判断子进程是否还活着,是否还在运行, 如果子进程还会运行会
反回一个True
p.terminate() #给操作系统发送一个结束进程的信号,然后操作系统帮他结束进程
print(p.is_alive()) #结束了进程,再查看的子进程是否还在运行,这时候就会返回False
既然不是一个id的,那么是否是一个空间的呢?
from mulitiprocessing import Process
num = 100 #这是全局变量这个大家都知道吧 ,那么接下来的几行注释就是打印结果
def f1():
global num
num = 3
print("子进程中的num") # 结果 3
print(num) #结果100 先说一下这里是两个一百,首先是先打印一个全局变量100
#等执行子进程的时候,子进程会把父进程的内容复制一遍,再次打印父进程内容
#所以就是两个100
if __name__=="__main__":
p = Process(target = f1,)
p.start()
p.join()
print("主进程中的num",num) #结果100
最后结果就是 发现父进程是全局空间,子进程是局部空间 ,子进程再怎么global改变全局变量,父进程里的
num都没变,父进程永远都是一个空间,子进程是一个空间,那么子进程再怎么修改自己所在的空间里的num,父进程
所在的空间的num都没变, 这俩的空间跟全局,局部没任何关系,这块有点抽象,大家理解一下.
所以子进程跟父进程之间是空间隔离的.
import time
from multiprocessing import Process
def f1():
time.sleep(3)
print('xxxx')
def f2():
time.sleep(5)
print('普通子进程的代码')
if __name__ == '__main__':
p = Process(target=f1,)
p.daemon = True #这个就是守护进程 ,p.daemon = True 将该进程设置为守护进程,必须写在start之前,意思如果我的主进程代码运行结束了,你这个子进程不管运行到什么地方,都直接结束
p.start()
p2 = Process(target=f2,)
p2.start()
p2.join()
print('主进程结束')
这个最后打印完了就是先打印主进程"主进程结束" 再打印p2结果,p1不打印,这就是守护进程
开启一个普通的子进程来验证一下守护进程的结束只和主进程的代码运行结束有关系,而整个程序的结束需要主进程和普通的子进程的代码都运行结束才结束
守护进程会跟跟着父进程的代码运行结束,就结束
但如果加上时间就不一样了
如果p1时间比p2时间短 ,p2中间加一个阻隔的话join(),先不打印父进程,打印子进程,的话,那么守护进程时间快
守护进程也就被打印了.所以而整个程序的结束需要主进程和普通的子进程的代码都运行结束才结束
守护进程会跟跟着父进程的代码运行结束,就结束
好好理解一下,打印一下,很简单的.
首先呀 互斥锁,同步锁,进程锁 这三个锁是同一个锁,只不过是三种叫法 ,不必纠结 ,叫什们都行
import time
from multiprocessing import Process,Manager,Lock
def f1(m_d,l2): #OK 方法能先说一下,锁是Lock, 数据共享是Manager
with l2: #with l2 是锁的 一种简写 ,直接with锁的对象,就把内容锁住了
#l2.acquire() #这个就是锁的原来的样子了,先锁住
tmp = m_d['num'] # 中间这段代码,是执行的内容,大家看一下咋回事就行,
tmp -= 1
time.sleep(0.1)
m_d['num'] = tmp
# l2.release() #再开锁 ,这就是锁的写法
if __name__ == '__main__':
m = Manager() #这个呢是数据共享,然后创建一个对象 m 随便定义一个变量
l2 = Lock()
m_d = m.dict({'num':100}) #然后传共享参数,就跟小黄车一样哈,虽然小黄车快黄了
p_list = []
for i in range(10): #创建10个进程
p = Process(target=f1,args=(m_d,l2)) 把共享属性传上去
p.start()
p_list.append(p) #为什们要加进一个列表里面呢,是因为,我们要统一把10个进程
[pp.join() for pp in p_list] #都加上join(),一是内容需要,另一个就是,当我们创建很多个进程
print(m_d['num']) #的时候,操作顺序不是我们能决定的,是操作系统来决定的,不加
#join的话,说不好他先操作那个进程,那不就乱了套了吗,所以每个都加上join ,这样10个进程都能按顺序操作了.这是个很重要的一个知识点,一定要 记住了....
锁呢是将10个进程一个一个的锁住,打印的时候不乱套,要不然都进来的话数据内容就乱了
这块跟join() 有点绕.join是让操作系统 一个一个排序的进行进程操作, 而锁呢是将进程内容给锁起来,让内容
一个一个操作,锁是跟进程内容有关.
数据共享就是10个进程,都能用这个属性
from multiprocessing import Process,Queue
q = Queue(3) #创建一个队列对象,队列长度为3,先进先出
q.put(1) #输入内容
# print('>>>>>',q.qsize()) #返回当前队列的内容长度
print(q.full()) #查看队列是否都满了没满就返回False
q.put(2)
# print('>>>>>',q.qsize())
q.put(3)
print(q.full())
print(q.get()) #打印内容
print(q.get())
print(q.get())
print('是不是空了呀:',q.empty())
队列大家打印一下,就可以了
又来一个for循环,这个就是为了让所有的所有的进程加join的,哈哈哈..看下数据共享跟锁
那块的那段话就知道了..
import time
from multiprocessing import Process
def f1():
time.sleep(0.5)
print('xxx')
if __name__ == '__main__':
p_list = []
#for循环创建子进程,并且完成主进程等待所有子进程执行结束,才继续执行
for i in range(10):
p = Process(target=f1,)
p.start()
p_list.append(p)
p.join()
[pp.join() for pp in p_list]
print('主进程结束')
OK 东西有点多,不过都是一些方法而已大框没变,里边加东西就可以了
大家好好记一下,练一下,记住多练就好了.