(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')
'''