进程
从1946年至今,计算机的发展已经走过了近百年,在硬件方面,计算机的运行效率和处理速度也得到了飞速的提升,而软件方面,随着硬件能力的提升,软件的性能和能力也有了质的飞跃,计算机在运行时伴随着无数的程序执行,这些程序和系统的共同运行才促成了我们意愿中的计算机的运行结果。
在计算机内,程序不运行时是执行文件,当程序运行时便是一个进程。
多进程
从最早的计算机CPU每秒钟5000次到现在的每秒钟2.8亿次,计算机的性能得到了巨大的提升,这也促使了计算机内多任务的产生,当多个程序同时执行时便是多进程,但实质上CPU处理进程仍是单个执行的,以单核CPU为例,因为现在CPU的处理速度非常快,所当用户从一个进程切换到另一个进程时,因为计算机的响应速度非常快,所以虽然实质上计算机在执行这些进程是来回执行的,但是从用户的角度来看便是多个进程同时进行。
python实现多进程
import multiprocessing,time #导入time包以及创建多进程的包multiprocessing
def a1():
for i in range(10):
print('跳舞',i)
time.sleep(1)
def a2():
for i in range(10):
print('wer',i)
time.sleep(1)
if __name__=='__main__': #声明以下是主进程运行时执行的代码
p1 = multiprocessing.Process(target=a1)#将函数a1作为进程加载
p2 = multiprocessing.Process(target=a2)#将函数a2作为进程加载
p1.start()#开始运行进程p1
p2.start()
print("结束")
以上代码执行时会看到,先打印了结束,再开始执行进程p1和p2的代码,这是因为p1和p2是属于改脚本(*.py)的子进程,只有当主进程**后,子进程才会**执行,需要注意的是这个写法即使主进程已经运行完毕结束了,如果子进程仍未运行完毕,那么子进程仍会继续运行。
阻塞
from multiprocessing import Process
a=1
def a1():
global a
a+=1
print("进程1",a)
def a2():
global a
a+=5
print("进程2",a)
if __name__ == '__main__':
p1=Process(target=a1)
p2=Process(target=a2)
# x=input("请输入")
p1.start()
p2.start()
x = input("请输入")#先执行主函数,阻塞
print("开始")
上述代码执行后可以发现,两个进程内的函数虽然调用了全局变量,然而这并没有对彼此之间的输出结果造成影响,所以进程实际上是将代码复制了一份用于自己单独执行,两者之前互不影响。
进程间的通信
from multiprocessing import Queue#Queue用于创建队列
q=Queue(4)#声明队列的大小为4
q.put("第1个")#向队列内填充内容
print(q.empty())#判断队列是否为空
print(q.qsize(),q.full())#q.qsize()用于展示队列内存储的数量 q.full()用于判断队列是否已满
q.put("第2个")
print(q.qsize(),q.full())
q.put("第3个")
print(q.qsize(),q.full())
print("Start")
q.put("第4个")
print("Hello")
print(q.qsize(),q.full())#q.qsize()输出里面的个数,q.full()判断是否为满
while q.qsize()>0:
print(q.get())#获取队列内的内容
print(q.empty())#判断是否为空
这个队列需要注意一个地方,如果使用put往队列内添加内容,如果队列已经满了,那么这个put语句会一直等待队列有空为止,如果不希望出现这种耗费资源的情况,一种方法是确定队列未满再添加,另一种则是设置等待时间q.put(timeout=2),这里设置的是超时两秒,即只等待两秒,同理get也可以设置超时时间,此外,get获取的是最先放入的数据,形象点理解则是:
队列像是一个单向的管子,put从一端把数据放入这个管子(队列),那么get只能从另一端获取,也就是只能按照放入的顺序获取数据。
线程
线程也称为轻进程,因为相比较进程而言,线程占用的资源的更少,不过不同的地方在于进程拥有占有一定的系统资源的能力,一般来说进程是占有系统资源的基本单位,但是线程则不一样,线程只能访问它所隶属的进程的资源,而线程本身并不能拥有系统资源。
进程拥有一个或一个以上的线程。
import time
from threading import Thread
a=10
def a1():
global a
for i in range(10):
a+=1
print("进程1",a)
time.sleep(1)
def a2():
global a
for i in range(10):
a+=1
print("进程2",a)
time.sleep(1)
if __name__ == '__main__':
t1=Thread(target=a1)
t2=Thread(target=a2)
t1.setDaemon(True)#设置成守护线程
t2.setDaemon(True)
# t2.setDaemon(False)
t1.start()
# t1.join() 先执行他线程t1
t2.start()
print("结束")
进程中创建线程
from multiprocessing import Process,Queue
from threading import Thread
#进程里面套线程
def aa(q):
q.put([1,2,3,4,5])
def a1(q):
t1=Thread(target=aa,args=(q,))
t1.start()
t1.join()
def bb(q):
try:
c=q.get()
print(c)
except:
print('空了')
def b1(q):
t2=Thread(target=bb,args=(q,))
t2.start()
t2.join()
if __name__ == '__main__':
q=Queue(3)
p1=Process(target=a1,args=(q,))
p2=Process(target=b1,args=(q,))
p1.start()
p2.start()
作业
"""
创建两个进程:进程A和进程B,用jcq消息队列实现他们的通信。
1、进程A里创建两个线程:线程A1 、线程A2.
在线程A1里创建一个a列表 [1,2,3,4,5,6], 用消息队列传递给线程A2,线程A2.
对列表进行筛选,删除掉奇数。然后用jcq消息队列发送给进程B
2、在进程B里创建两个线程:线程B1、线程B2
线程B2.接受进程A发过来的数据,并把这些数据,原封不动的用线程消息队列传递给线程B1
线程B1求出所有数的和并打印结果
"""
from multiprocessing import Process, Queue, Lock
from threading import Thread
import queue
def A1(q):
a=list(range(1,3))
q.put(a)
def A2(q):
while q.qsize()>0:
a=q.get()
for i in a:
if i%2==0:
q.put(i)
def A(q):
at1=Thread(target=A1,args=(q,))
at2=Thread(target=A2,args=(q,))
at1.start()
at1.join()
at2.start()
at2.join()
def B1(q):
num=0
while q.qsize()>0:
num=q.get()+num
print(num)
def B2(q):
return q
def B(q):
bt1=Thread(target=B1,args=(q,))
bt2=Thread(target=B2,args=(q,))
bt2.start()
bt2.join()
bt1.start()
bt1.join()
if __name__ == '__main__':
q = Queue(10)
p1=Process(target=A,args=(q,))
p2=Process(target=B,args=(q,))
p1.start()
p2.start()
#多任务文件拷贝
from multiprocessing import Process,Queue
import time
def fileopen(q):
lb=[]
with open('a.txt','r') as f:
rdata=f.readline()
while len(rdata)>0:
lb.append(rdata)
rdata=f.readline()
q.put(lb)
def filecopy(q):
with open('b.txt','w') as f:
while q.qsize()>0:
a=q.get()
for i in a:
f.write(i)
if __name__ == '__main__':
q=Queue(3)
p1=Process(target=fileopen,args=(q,))
p2=Process(target=filecopy,args=(q,))
p1.start()
time.sleep(5)
p2.start()