day37

(1)进程间数据互相隔离
(2)进程调度算法
(3)进程对象及其他方法
(4)守护进程
(5)互斥锁
(6)with 上下文管理
(7)队列
(8)IPC通信

# 进程间数据互相隔离
'''
from multiprocessing import Process
import os, time

a = 10


def task(n):
    global a
    a = 99
    print('task is running.', os.getpid())
    time.sleep(n)
    print('task is done.', os.getpid())
    print(a)


if __name__ == '__main__':
    p = Process(target=task, args=(2,))
    p.start()
    p.join()
    print('主进程----->', os.getpid())
    print(a)

# 进程之间的数据是相互隔离的,子进程会拷贝父进程的数据,对子进程中的数据进行修改,不会影响父进程中的数据
'''

# 进程调度算法
'''
# 1、先进先出算法
# 2、短进程优先
# 3、时间片轮转
# 4、多级反馈队列
'''

# 进程对象及其他方法
'''
from multiprocessing import Process, current_process
import os, time


def task(n):
    print('父进程PID:', os.getppid())          # getppid ---> 获取父进程PID
    print('task is running.', os.getpid())
    time.sleep(n)
    print('task is done.', current_process().pid)       # current_process() ---> 当前进程对象
    print(current_process().is_alive())        # is_alive 判断进程是否存活,若判断本身则一定为true


if __name__ == '__main__':
    p = Process(target=task, args=(2,))
    p.start()
    p.join()
    p.terminate()       # 终止进程,向操作系统发送结束进程信号,操作系统需要时间来杀死进程 (不能自己终止自己)
    # time.sleep(0.1)
    print(p.is_alive())
    print('主进程----->', os.getpid())
'''

# 守护进程 (daemon)
'''
# 将子进程A设置为主进程的守护进程,当主进程结束时,子进程A也一起结束
from multiprocessing import Process
import os, time


def task(n, tag):
    print('task %s is running.' % tag, os.getpid())
    time.sleep(n)
    print('task %s is done.' % tag, os.getpid())


if __name__ == '__main__':
    p1 = Process(target=task, args=(2, '1'))
    p2 = Process(target=task, args=(2, '2'))
    p1.daemon = True         # 将进程p设置为主进程的守护进程(必须在进程启动之前设置)
    p1.start()
    p2.start()
    print('主进程----->', os.getpid())
    time.sleep(0.5)
'''

# 互斥锁
'''
# 在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。
# 每个对象都对应于一个可称为"互斥锁"的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。 (百度百科)
from multiprocessing import Process, Lock
import time
import random
import json


def search():
    with open('ticket', mode='r', encoding='utf-8') as f:
        dic = json.load(f)
        return dic['ticket']


def buy():
    with open('ticket', mode='r', encoding='utf-8') as f1:
        dic = json.load(f1)
        print(f'当前余票数量:{dic["ticket"]}')
        time.sleep(random.randint(1,3))          # 模拟网络延迟
    if dic['ticket'] > 0:
        dic['ticket'] -= 1
        with open('ticket', mode='w', encoding='utf-8') as f2:
            json.dump(dic, f2)
            print('买票成功')
    else:
        print('余票不足')


def task(mutex):
    search()
    # # 买前加锁
    # mutex.acquire()
    # buy()             # 进程变为串行执行
    # # 买完后释放锁
    # mutex.release()
    with mutex:             # with 上下文处理
        buy()


if __name__ == '__main__':
    mutex = Lock()          # 在主进程中创建锁
    for i in range(10):
        t = Process(target=task, args=(mutex,))
        t.start()
'''

# with 上下文管理
'''
# (1)只要出现with语句,那么对象中的__enter__就会触发运行,并且将返回值赋给as声明的变量名
# (2)之后再运行with中的代码块
# (3)with代码块运行结束后,触发__exit__的运行
class MyClass:
    def __init__(self, file_name, mode, encoding):
        self.file_name = file_name
        self.mode = mode
        self.encoding = encoding

    def __enter__(self):
        print('出现with语句,对象的__enter__就会被触发,返回值赋值给as声明的变量')
        self.file = open(self.file_name, mode=self.mode, encoding=self.encoding)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):      # __exit__()中的三个参数分别代表异常类型,异常值和追溯信息
        print('with中代码块执行完毕后执行__exit__')
        self.file.close()
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        # return True       # 如果__exit()__返回值为True,那么异常就会被清空,后续代码会正常运行


with MyClass('ticket', 'r', 'utf-8') as f:
    print(f.read())
    # print(asd)              # 触发__exit__,之后的代码不会运行
    print('----->')         # 出错后不会运行,如果__exit()__返回值为True,那么异常就会被清空,后续代码会正常运行

print('end......')          # 出错后不会运行,如果__exit()__返回值为True,那么异常就会被清空,后续代码会正常运行
'''

# 队列
'''
# 先进先出
from multiprocessing import Queue

q = Queue(3)         # 实例化得到对象,默认队列长度很大,可指定队列长度

q.put('xxx')        # put ---> 向队列中放值
q.put(123)
q.put(999)
# q.put(999)      # 若超出队列长度,则程序会一直卡住,直到对方取走一个值之后
# q.put(999, timeout=2)       # 可指定等待时间,经过等待时间后若对方还未取走一个值,则抛出异常 (异常处理)
# q.put_nowait(999)     # 不等待,若不能放值则直接抛出异常

q.get()             # get ---> 从队列中取值
q.get()
q.get()
# q.get()         # 若超出队列长度,则程序会一直卡住,直到对方放入一个值之后
# q.get(timeout=2)        # 可指定等待时间,经过等待时间后若对方还未放入一个值,则抛出异常
# q.get_nowait()      # 不等待,若取不到值则直接抛出异常

print(q.full())     # 判断队列是否为满
print(q.empty())    # 判断队列是否为空
'''

# IPC通信(Inter Process Communication 进程间通信)
'''
import os
from multiprocessing import Process, Queue


def task1(q):
    q.put(123)
    print('task1 PID:%s' % os.getpid())


def task2(q):
    print('task1 PID:%s' % os.getpid())
    print(q.get())
    print(q.get())


if __name__ == '__main__':
    q = Queue(5)
    p1 = Process(target=task1, args=(q,))
    p1.start()
    p2 = Process(target=task2, args=(q,))
    p2.start()

    q.put('xxx')
'''

 

posted @ 2020-08-24 20:15  板鸭没有腿  阅读(96)  评论(0)    收藏  举报