首页 > 系统服务 > 详细

并发编程之进程

时间:2019-05-06 17:37:01      阅读:148      评论:0      收藏:0      [点我收藏+]

一 、进程理论

    程序:一堆代码

    进程:正在运行的程序

    进程是一个实体。每一个进程都有它自己独立的内存空间

 

同步和异步:针对任务的提交方式

      同步:提交任务之后原地等待任务的返回结果,期间不做任何事

      异步:提交任务之后,不等待任务的返回结果,执行运行下一行代码

 

阻塞与非阻塞:针对程序运行的状态

      阻塞:遇到 io 操作     》》》阻塞态

      非阻塞:就绪或者运行态   》》》就绪态,运行态

 

二 、开启进程的两种方式(***)

    

    1、

from multiprocessing import Process
import time

def task(name):
print(‘%s is running‘%name)
time.sleep(3)
print(‘%s is over‘%name)


# 注意,在windows系统中,创建进程会将代码以模块的方式从头到尾加载一遍
# 一定要写在if __name__ == ‘__main__‘:代码块里面
# 强调:函数名一旦加括号,执行优先级最高,立刻执行
if __name__ == ‘__main__‘:
p1 = Process(target=task,args=(‘egon‘,)) # 这一句话只是实例化了一个Process对象
p1.start() # 告诉操作系统创建一个进程
print(‘这是一个父程序‘)

 

    2、

from multiprocessing import Process
import time

class MyProcess(Process):

def __init__(self,name):
super().__init__()
self.name = name

# 必须写run方法
def run(self):
print(‘%s is running‘%self.name)
time.sleep(1)
print(‘%s is end‘%self.name)

if __name__ == ‘__main__‘:
obj = MyProcess(‘egon‘)
obj.start()
print(‘这是一个父程序‘)

 

三 、进程对象的 join 方法(***)

 

from multiprocessing import Process
import time

def task(name,n):
print(‘%s is running‘%name)
time.sleep(n)
print(‘%s is over‘%name)


if __name__ == ‘__main__‘:
start_time = time.time()
p_list = []
for i in range(3):
p = Process(target=task,args=(‘子进程%s‘%i,i))

p.start()     # 千万要知道,这句话只是告诉操作系统需要进程
        p_list.append(p)
for i in p_list:
i.join() # 主进程等待子进程结束 才继续运行
   print(‘这是一个主程序‘,time.time()-start_time)

 

四 、 进程之间内存隔离(***)

 

from multiprocessing import Process

x = 100
def task():
global x
x =1

if __name__ == ‘__main__‘:
p = Process(target=task)
p.start()
p.join()
print(‘这是主程序‘,x)

进程是程序的执行单位,线程是CPU的执行单位。程序之间的数据是互相独立运行的,因此进程运行的时候并不会影响其他进程,导致进程混乱。

 

五 、进程对象其他相关方法

 

from multiprocessing import Process,current_process
import time
import os

def task():
print(‘%s is running‘%os.getpid())
time.sleep(3)
print(‘%s is over‘%os.getppid())


if __name__ == ‘__main__‘:
p1 = Process(target=task)
p1.start()
# p1.terminate() # 杀死子进程
# time.sleep(0.1)
# print(p1.is_alive()) # 判断子进程是否存活
print(‘主‘)

 

六 、僵尸进程与孤儿进程

        两种情况下会回收子进程的 pid 等消息

            1 、父进程正常结束

            2 、join 方法

        孤儿进程:父进程意外死亡

        Linux下:init 孤儿福利院:用来回收孤儿进程所占用的资源

 

七 、守护进程:父进程结束了子进程必须也跟着结束

 

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=(‘egon总管‘,))
p.daemon = True # 必须在p.start开启进程命令之前声明
p.start()
print(‘皇帝jason正在死亡‘)

 

八 、互斥锁(***)    千万不要随意使用,意思就是说能不用就尽量不用

 

  牺牲了效率但是保证了数据的安全

 

  锁一定要在主进程中创建,给子进程去用

  解决多个进程操作同一份数据,造成数据不安全的情况

  加锁会将并发变成串行

  锁通常用在对数据操作的部分,并不是对进程全程加锁

   

  mutex.acquire() # 抢锁 一把锁不能同时被多个人使用,没有抢到的人,就一直等待锁释放
  buy(i)
  mutex.release() # 释放锁

 

关于抢票延迟的例子  

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

def search(i):
with open(‘info‘,‘r‘,encoding=‘utf-8‘) as f:
data = json.load(f)
print(‘用户查询余票数:%s‘%data.get(‘ticket‘))


def buy(i):
# 买票之前还得先查有没有票!
with open(‘info‘,‘r‘,encoding=‘utf-8‘) as f:
data = json.load(f)
time.sleep(random.randint(1,3)) # 模拟网络延迟
if data.get(‘ticket‘) >0:
data[‘ticket‘] -= 1 # 买票
with open(‘info‘,‘w‘,encoding=‘utf-8‘) as f:
json.dump(data,f)
print(‘用户%s抢票成功‘%i)
else:
print("用户%s查询余票为0"%i)


def run(i,mutex):
search(i)
mutex.acquire() # 抢锁 一把锁不能同时被多个人使用,没有抢到的人,就一直等待锁释放
buy(i)
mutex.release() # 释放锁


if __name__ == ‘__main__‘:
mutex = Lock()
for i in range(10):
p = Process(target=run,args=(i,mutex))
p.start()

 

并发编程之进程

原文:https://www.cnblogs.com/SlookUp/p/10820648.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!