进程与多进程

python并发编程之进程

一、进程中的名词要清楚在程序中是什么意思?

进程与程序的区别:程序仅仅只是一堆代码而已,而进程指的是程序的运行过程.

进程:一个程序在一个数据集上的一次动态执行过程.

***(需要强调的是:同一个程序执行两次,那也是两个进程)***

并发与并行

并发:是伪并行,即看起来是同时运行,单个cpu+多道技术就可以实现并发,(并行也属于并发)

并行:同时运行,只有具备多个cpu才能实现并行

同步与异步:

同步执行:一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行。

异步执行:一个进程在执行某个任务时,另外一个进程无需等待其执行完毕,就可以继续执行,当有消息返回时,系统会通知进行处理,这样可以提高执行效率

进程的创建

multiprocessing模块介绍

multiprocess模块的功能众多:支持子进程,通信和共享数据,执行不同形式的同步,提供了process、Queue、Lock等组件。

多进程的创建

简单的两种方法:函数(直接代入运行)和用类类包装进程对象(继承)
	from multiprocssing import Process
	import time
	
	#1.函数(直接代入运行)
	
	def foo(i):
		print("say hi", i )
	if __name__ =="__main__":
		for i in range(10):
			p1 = Process(target=foo, args=(i,))
			p2 = Process(target=foo, args=(i,))
			p1.start()
			p2.start()
			
	#2用类来包装进程对象(Process继承)
	class MyProcess(Process):
		def __init__(self,arg):
			super(MyProcess,self).__init__()
			self.arg = arg
			
		def run(self):
			print("say hi", i)
			time.sleep(1)
		
		if __name__=="__main__":
			for i in range(10):
				p1 = MyProcess(i)
				p2 = MyProcess(i)
				p1.start()        #start会自动调用run
				p2.start()

daemon程序对比结果

#不加daemon守护进程
def foo(i):
    '''
    第一个方法:直接传入要运行的方法
    :param i:
    :return:
    '''
    print("say hi", i)

if __name__ =="__main__":
     for i in range(2):
         p = multiprocessing.Process(target=foo,args=(i,))          #target --要执行的方法
         p.start()                                                  #start  --启动进程
         print("end")

#结果:
    end
    say hi 0
    say hi 1
=========================================================================================
#加daemon守护进程
def foo(i):
    '''
    第一个方法:直接传入要运行的方法
    :param i:
    :return:
    '''
    print("say hi", i)

if __name__ =="__main__":
     for i in range(10):
         p = multiprocessing.Process(target=foo,args=(i,))          #target --要执行的方法
         p.daemon = True                                            #守护进程
         p.start()                                                  #start  --启动进程
         print("end")

#结果:
    end                           注: 因子进程设置了daemon属性,主进程结束,它们就随着结束了
=========================================================================================
#加daemon守护进程并做修改
def foo(i):
    '''
    第一个方法:直接传入要运行的方法
    :param i:
    :return:
    '''
    print("say hi", i)

if __name__ =="__main__":
     for i in range(2):
         p = multiprocessing.Process(target=foo,args=(i,))          #target --要执行的方法
         p.daemon = True                                            #守护进程
         p.start()                                                  #start  --启动进程
         p.join()                              #join()方法可以等待子进程结束后再继续往下运行
         print("end")

#结果:
    say hi 0
    say hi 1
    end

进程(锁)

进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题,竞争带来的结果就是错乱,如何控制,就是加锁处理
import multiprocessing
import sys
def worker_with(lock, f):
    with lock:                       # #with Lock的作用相当于自动获取和释放锁(资源)
        fs = open(f, 'a+')
        n = 10
        while n > 1:
            fs.write("Lockd acquired via with\n")
            n -= 1
        fs.close()
'''
with lock  和  lock.acquire()与lock.release()等价的
'''

def worker_no_with(lock, f):
    lock.acquire()
    try:
        fs = open(f, 'a+')
        n = 10
        while n > 1:
            fs.write("Lock acquired directly\n")
            n -= 1
        fs.close()
    finally:
        lock.release()


if __name__ == "__main__":
    lock = multiprocessing.Lock()
    f = "file.txt"
    w = multiprocessing.Process(target=worker_with, args=(lock, f))
    nw = multiprocessing.Process(target=worker_no_with, args=(lock, f))
    w.start()
    nw.start()
    print("end")

进程池:

#一:使用进程池(非阻塞,apply_async)
#coding: utf-8
from multiprocessing import Process,Pool
import time

def func(msg):
    print( "msg:", msg)
    time.sleep(1)
    return msg

if __name__ == "__main__":
    pool = Pool(processes = 3)
    res_l=[]
    for i in range(10):
        msg = "hello %d" %(i)
        res=pool.apply_async(func, (msg, ))   #维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
        res_l.append(res)
    print("==============================>") #没有后面的join,或get,则程序整体结束,进程池中的任务还没来得及全部执行完也都跟着主进程一起结束了

    pool.close() #关闭进程池,防止进一步操作。如果所有操作持续挂起,它们将在工作进程终止前完成
    pool.join()   #调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束

    print(res_l) #看到的是<multiprocessing.pool.ApplyResult object at 0x10357c4e0>对象组成的列表,而非最终的结果,但这一步是在join后执行的,证明结果已经计算完毕,剩下的事情就是调用每个对象下的get方法去获取结果
    for i in res_l:
        print(i.get()) #使用get来获取apply_aync的结果,如果是apply,则没有get方法,因为apply是同步执行,立刻获取结果,也根本无需get

#二:使用进程池(阻塞,apply)
#coding: utf-8
from multiprocessing import Process,Pool
import time

def func(msg):
    print( "msg:", msg)
    time.sleep(0.1)
    return msg

if __name__ == "__main__":
    pool = Pool(processes = 3)
    res_l=[]
    for i in range(10):
        msg = "hello %d" %(i)
        res=pool.apply(func, (msg, ))   #维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
        res_l.append(res) #同步执行,即执行完一个拿到结果,再去执行另外一个
    print("==============================>")
    pool.close()
    pool.join()   #调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束

    print(res_l) #看到的就是最终的结果组成的列表
    for i in res_l: #apply是同步的,所以直接得到结果,没有get()方法
        print(i)

详解:apply_async与apply

详解:apply_async与apply

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值