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,其他类型则共享不了

猜你喜欢

转载自www.cnblogs.com/hello-yuanjing/p/9932496.html
今日推荐