进程

1、进程理论

  进程就是一个正在进行的过程或者一个任务,

  1.1、进程与程序区别:

    程序是一堆代码,进程是指的是程序的运行过程

  1.2、多道技术:

      空间上的复用、时间上的复用

    多个任务复用、共享内存空间,进程之间的内存空间是相互隔离的

    多个任务复用、共享cpu时间,cpu在多个任务之间来回切换

    1、一个任务占用cpu的时间过长会被操作系统强行剥夺走cpu的执行权限,为了保证一个并发效果,降低效率。

    2、一个任务遇到io操作会被操作系统剥夺走cpu的执行权限,为了实现 并发效果,这种情况下的并发可以提升效率。   

2、开启进程的两种方式

  方式一:

from multiprocessing import Process
import time

def task(name):
print('%s is running'% name)
time.sleep(3)
print('%s is down' % name)

if __name__ == '__main__':
obj = Process(target=task,args=('yzn',))
obj.start() # 操作系统发送一个开启子进程的信号
print('主')
输出结果:
  主
  yzn is running
  yzn is down

  方式二:
from multiprocessing import Process
import time
class Myprocsess(Process):

def __init__(self,name):
super().__init__()
self.name = name
def run(self):
print('%s is running' % self.name)
time.sleep(3)
print('%s is down' % self.name)

if __name__ == '__main__':
p = Myprocsess('yzn')
p.start()
print('主')

3、进程对象join方法使用

  让主进程原地等待,等待子进程运行完毕,不会影响子进程的执行

from multiprocessing import Process
import time

def task(name):
print('%s is running'% name)
time.sleep(3)
print('%s is down' % name)

if __name__ == '__main__':
obj = Process(target=task,args=('yzn',))
obj.start() # 想操作系统发送一个开启子进程的信号
obj.join()  #添加join方法
print('主')

4、进程之间内存隔离

  进程自检内存空间是相互隔离的

from multiprocessing import Process
n =100
def task():
global n
print(n,'1')  #通过global复制全局的n 100,1
n =0
print(n,'2')  #获取到n为0 0,2
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print(n)  #获取全局中的值100
输出结果为:
  100,1
  0,2
  100

5、进程对象其它相关方法

获取子进程的pid,主进程的pid

可以使用corrent_process 和getpid

  1、corrent_process

from multiprocessing import Process,current_process
import time
def task():
print('%s is running' %current_process().pid)
time.sleep(30)
print('%s is done' %current_process().pid) # 查看子类pid
if __name__ == '__main__':
p =Process(target=task)
p.start()
print('主',current_process().pid) # 查看父类pid

  2、getpid
from multiprocessing import Process
import time,os
def task():
print('% is running' %os.getpid()) #子进程pid
time.sleep(3)
print('%s is done'%os.getpid()) #子进程pid
if __name__ == '__main__':
p = Process(target=task)
p.start()
print('主',os.getpid()) # 主进程pid

6、僵尸进程与孤儿进程

僵尸进程解决办法:

  1、主进程可以用过join()方法回收子进程(主动回收)

  2、当主进程死了以后,操作系统自己可以发起回收(被动回收)

7、守护进程

  守护进程本质就是一个子进程,该子进程的生命周期<=被守护进程的生命周期

from multiprocessing import Process
import time
def task(name):
print('太监%s'%name)
time.sleep(3)
print('太监%s死了' %name)
if __name__ == '__main__':
p = Process(target=task,args=('dsb',))
p.daemon=True  #守护进程,在启动进程之前
p.start()
time.sleep(1)
print('皇上:egon正在die')
输入结果:
  太监dsb
  皇上:egon正在die

备注:这里设置等待时间time.sleep(1)时间没有超过子进程中的time.sleep(3)等待3秒下面的内容就不会显示,可以使用join()方法

8、互斥锁

  互斥锁:共同操作一个文件造成错乱

加载 multiprocessing包中的Lock模块

import json
import time
import random
from multiprocessing import Process,Lock

def search(name):
with open('db.json','rt',encoding='utf-8') as f:
dic = json.load(f)
time.sleep(1)
print('%s查看余票为 %s' % (name, dic['count']))

def get(name):
with open('db.json', 'rt', encoding='utf-8') as f:
dic = json.load(f)
time.sleep(random.randint(1, 3))
if dic.get('count') > 0:
dic['count'] -= 1
with open('db.json', 'w', encoding='utf-8') as f:
json.dump(dic, f)
print('%s购票成功!!' % name)
else:
print('%s 查看到没有票了' % name)


def task(name,mutex):
search(name)
mutex.acquire() # 抢锁 对search进行加锁
get(name)
mutex.release() # 解锁 对数据进行修改的时候进行解锁


if __name__ == '__main__':
mutex = Lock()  #使用Lock模块
for i in range(1, 10):
p = Process(target=task, args=('路人%s' % i,mutex))
p.start()
# p.join() # join只能将进程的任务整体编程串行
原文地址:https://www.cnblogs.com/yangzhaon/p/10822500.html