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,其他类型则共享不了
原文地址:https://www.cnblogs.com/hello-yuanjing/p/9932496.html