• 2018.11.08python学习第三十六天


    一:守护进程

    # 守护进程:顾名思义,就是一个进程守护着另一个进程,指的是两个进程之间的关系。
    # 特点:就是守护进程在被守护进程死亡时,也会跟着被守护进程的死亡而死亡。
    
    使用方法:
    from multiprocessing import Process
    import time
    def task():
    	print('hello')
    	time.sleep(3)
    	print('see u')
     
    if __name__ == '__main__':
        p = Process(target = task)
        p.daemon = True
        p.start()
        time.sleep(3) 			#
        print('process is running')
        
    # 1.daemon必须在start之前写
    # 2.当主进程死亡时,守护进程也会死亡,如果注释掉time.sleep(3),守护进程还没来得及执	  行就死亡。
    

    二:互斥锁

    #当多个进程对统一资源进行读写时,这些进程会对这个资源产生竞争,从而导致数据错乱,解决方法就是将这些进程变成串行。那么我们可以用下面的办法来解决:
    1.join 	#把整个进程变成串行,并且顺序是固定的。
    # 虽然join可以将进程变成串行,但是串行是顺序是我们人为固定的,对于这些竞争的进程来说不公# 平,而且,当我们需要部分串行的时候,整个时候join显然不是很适用
    # 那么由此产生了另一种办法
    2.互斥锁 # 可以实现并程中的部分串行,
    
    使用方法
    from multiprocessing import Process,Lock
    
    def task1(lock):
    	lock.acquire()
    	for i in range(10000):
    		print('===')
    
    def task2(lock):
        lock.acquire()
        for i in range(10000):
            print("===============")
        lock.release()
    
    def task3(lock):
        lock.acquire()
        for i in range(10000):
            print("======================================")
        lock.release()
    
    if __name__ == '__main__':
    	mutex = lock()
    	p1 = Process(target=task1,args=(mutex,))
        p2 = Process(target=task2,args=(mutex,))
        p3 = Process(target=task3,args=(mutex,))
        
        p1.start()
    	p2.start()
    	p3.start()
        print('over')
        
    # 1.先导入模块Lock
    # 2.创建一个锁对象 mutex = Lock()
    # 3.将进程竞争的资源上锁
    
    
    注意:所有的进程上锁的话必须使用同一把锁

    三:互斥锁应用

    抢票程序
    from multiprocessing import Process,Lock
    import json,time,random
    
    # file = {"count":1}		# json 格式
    def show_ticket(name):
    	# 模拟网络延迟
    	time.sleep(random.randint(1,5))
    	with open ('filename','rt',encoding = 'utf-8') as f:
    		data = json.load(f)
    		print('%s查看了车票剩余:%s' %(name,data['count']))
    		
    def buy_ticket(name):
    	with open ('filename','rt',encoding = 'utf-8') as f:
    		data = json.load(f)
    		if data['count'] > 0:
    			data['count'] -=1
    			time.sleep(random.randint(1,3))
    			time.sleep(random.randint(1,3))
    			with open('filename','wt',encoding = 'utf-8') as f1:
    				json.dump(data,f1)
    				print('%s购票成功' %name)
    				
    def task(lock,name):
    	show_ticket(name)
    	lock.acquire()
    	buy_ticket(name)
    	lock.release()
    	
    
    if __name__ == '__main__':
    	lock = Lock()
    	for i in range(1,11):
    		p = Process(target = task,args = (lock,'客户%s' %i))
    		p.start()
    

    四:ipc

    # 进程彼此之间互相隔离,要实现进程间通信(ipc/inter process commucation),
    # multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的
    
    创建队列的类(底层就是以管道和锁定的方式实现的):
    # Queue([maxsize]):创建共享进程队列,Queue是多进程安全的队列,可以使用Queue实现多进# 程之间的数据传递
    
    参数介绍
    1.maxsize		#是队列中允许最大项数,省略则需大小限制
    
    方法一介绍
    q = Queue()
    
    1.q.put #方法用以插入数据到队列中,put方法还有两个参数可以选择:blocked和timeout。 # 如果block为True(默认),并且timeout为正值,该方法会阻塞timeout指定的时间,直到 # 该队列有剩余的空间。如果超时,会抛出Queue.Full异常。
    # 如果block为False,但是Queue已经满了,会立即抛出Queue.Full异常。
    2.q.get #方法可以从队列取走一个元素(注意是取走)。同样有两个方法参数可以选择:block和# timeout.
    # 如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,# 会抛出Queue.Empty异常。
    # 如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如# 果队列为空,则立即抛出Queue.Empty异常.
    3.q.get_nowwait() 	# 同q.get(False)
    4.q.put_nowwait()	# 同q.put(False)
    5.q.empty()		# 调用此方法时q为空则返回True,该结果不可靠,如在返回True的过程中又					 添加了项目。
    6.q.full()		# 调用此方法时q已满则返回True,该结果不可靠,如在返回True的过程中队					 列中的项目又被取走了。
    7.q.qsize()		# 返回队列中目前项目正确数量,结果也不可靠,和上述一致。
    
    举例
    from multiprocessing import Queue
    
    # 创建一个队列
    q = Queue()
    
    # 存入数据
    q.put('hello)		# 存入str
    q.put(['1','2','3'])	# 存入list
    q.put(1)			# 存入int
    
    # 读出数据
    print(q.get())
    print(q.get())
    print(q.get())
          
    # 阻塞操作
    q = Queue(3)		# 限制存放数据的个数
    
    # 存入数据
    q.put('hello',block = False)	# 不阻塞
    q.put(['1','2','3'],block = False)	# 不阻塞
    q.put(1,block =False)	# 不阻塞
    
    # 此时再存入一个数据q.put('word',block = False) 则会抛出Queue.Full异常
    # 如果是q.put('word',block = True)则不会抛出异常,会等到Queue有位置后再存入
          
    #  取出数据
    print(q.get(block=False))
    print(q.get(block=False))
    print(q.get(block=False))
          
    # 此时再取出一个数据print(q.get(block = False)) 则会抛出Queue.Empty异常
    # 如果是print(q.gte(block = True)则不会抛出异常,会等到Queue有数据后再取走
          
    
    方法二:
    # 导入Manager模块
    from multiprocessing import Process,Manager
    import time
    
    def task(dic):
    	print('subprocess is running')
    	li[0] = 1
    	print(li)
    	
    	
    if __name__ == "__main__":
    	m = Manager()
    	# 创建一个公共区域
    	li = m.list([100])
    	p = Process(target = task,args = (li,))
    	p.start()
    	time.sleep(3)
    	print(li)
    	
    # m = Manager()只能创建list和dict,其他类型则共享不了
    
  • 相关阅读:
    想写点啥?
    网站优化记录
    freemarker了解
    spring理解
    mybatis了解
    struts机制
    SSM整合时初始化出现异常
    常用的正则表达式
    MySQL数据库安装配置步骤详解
    完全卸载MySQL数据库,实现重装
  • 原文地址:https://www.cnblogs.com/hello-yuanjing/p/9932496.html
Copyright © 2020-2023  润新知