进程

狭义:正在运行的程序实例。

广义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,他是操作系统动态执行的基本单元。

python的进程都是并行的。

并行:两个进程同时执行一起走。

并发:逻辑上是两个线程同时进行,物理上是交替执行。

 import multiprocessing

 def fun1(i):
print(multiprocessing.current_process(),i) if __name__ == "__main__":
mp_lst = []
for i in range(100):
m = multiprocessing.Process(target=fun1,args=(i,))
m.start()
mp_lst.append(m) _ = [i.join() for i in mp_lst]

简单开启100个进程

python进程和线程的使用方式没啥区别

start() 开启进程

join() 等待,直到进程完成其工作并退出位置

为什么要使用__name__ == "__mian__"呢?

因为进程再创建时要导入目标函数的脚本,使用__name__ == "__mian__"方式来防止无限递归。

如果目标函数不在和开启进程同一个脚本中就不需要使用。

class Process():

    # TODO: set type of group to None
def __init__(self,
group: Any = ...,
target: Optional[Callable] = ..., #函数
name: Optional[str] = ..., #进程名
args: Iterable[Any] = ..., #参数
kwargs: Mapping[Any, Any] = ...,
*,
daemon: Optional[bool] = ...) #是否在后台运行进程
def start(self) #开启进程
def run(self) #目标函数
使用类开启多个进程

如何在后台运行进程

python没有守护进程,没有守护进程,没有守护进程 说三遍。

后台进程是一种典型的耗时执行模式,他不需要人为干预,但是可以与其他程序并发,python通过设置daemon选项设置后台进程。

后台进程不能有子进程,因为后台进程的父进程退出时它会终止,如果有子进程那么子进程就会变成游离状态。

 import multiprocessing

 class MyProcess(multiprocessing.Process):
def __init__(self):
super(MyProcess, self).__init__() def run(self):
print(self.name) a = MyProcess()
a.daemon = True #设置后台进程
a.start()

后台进程简单应用

杀死进程

 class MyProcess(multiprocessing.Process):
def __init__(self):
super(MyProcess, self).__init__() def run(self):
print(self.name) a = MyProcess() a.start() a.terminate() #杀死进程
time.sleep(5)
print(a.is_alive()) #判断进程存活
a.join()

杀死进程示例

进程不会被立刻杀死,需要一定时间。

p.exitcode 状态码

==0:表示没有错误

>0:表示进程遇到了错误并退出。

<0:表示进程被信号杀死了。

进程锁与递归锁同线程

信号量、事件都和线程一样

进程同步

python 3.2新增特性屏障barrier

import multiprocessing
from multiprocessing import Process,Barrier,Lock
import time def fun1(br,lockto):
br.wait() #屏障阻塞
now = time.time()
with lockto: #利用with获取和释放锁
print(multiprocessing.current_process().name,now) def fun2():
now = time.time()
print(multiprocessing.current_process().name,now) if __name__ == "__main__":
br = Barrier(2) #设置屏障要阻塞几个进程
lockto = Lock()
p1 = Process(target=fun1, args=(br, lockto), name="p1_prosess")
p2 = Process(target=fun1, args=(br, lockto), name="p2_prosess")
p3 = Process(target=fun2, name="p3_prosess")
p4 = Process(target=fun2, name="p4_prosess")
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join() 输出:
p3_prosess 1562118519.9697998
p2_prosess 1562118519.9697998
p1_prosess 1562118519.9697998
p4_prosess 1562118519.9768193

我们可以看到p1和p2的时间是完全相同的至于p3为什么也相同=。=俺电脑太棒了只能说,多测试几遍就有不同的值了不贴了。

这个屏障的作用就是wait阻塞住以后按照前面设置的阻塞进程的数量来拦截进程,我这里设置的是2个所以就第一个进程到达时阻塞直到第二个进程到达才一起释放。如下图:

利用进程管理器进行数据共享

 import multiprocessing

 def fun1(mg_dict,x,y):
mg_dict[x] = y if __name__ == "__main__":
mg = multiprocessing.Manager() #生成管理器对象
mg_dict = mg.dict() #创建共享字典 p_lst = [multiprocessing.\
Process(target=fun1,args=(mg_dict,i,i*2)) for i in range(10)] [p.start()for p in p_lst]
[task.join()for task in p_lst] print(mg_dict)

利用管理器共享数据

如果要访问数据也要加锁奥~

进程间通信

可以使用管道、队列

这里最主要想说是一个mpi4py的python模块,可以进行进程的点对点、广播、拓扑(订阅发布)的方式通信,但是一般大家都用rabitmq,不知道有没有必要写,我可以利用这个模块做什么呢?

可以使用他造轮子吗?但是有rbitmq这些还有必要造吗?有什么意义?感觉灵活度也不是很高。可以利用他再写一个类似celery的轮子?我觉得celery是可以重写因为大部分功能都用不上,减轻负重也不错。

最新文章

  1. MMORPG大型游戏设计与开发(服务器 AI 逻辑设定和状态结点)
  2. Java—图形处理
  3. SSH框架执行自己定义的SQL语句
  4. 通过Keepalived实现Redis Failover自动故障切换功能
  5. Android ViewPager使用详解(转)
  6. django-jinjia 集成
  7. 跳舞毯[XDU1005]
  8. ARM安装ROS- indigo
  9. Tortoisesvn单个文件夹checkout
  10. Java基础——序列化
  11. zookeeper学习记录
  12. Android中Socket通信案例
  13. Android开发之自定义圆形的ImageView的实现
  14. JSTL详解
  15. Sumdiv(各种数学)
  16. Android常见开源解决方案
  17. 用c#实现单链表(程序代码已经验证,完全正确)
  18. mac中利用brew实现多版本php共存以及任意切换
  19. 海量数据挖掘MMDS week7: 相似项的发现:面向高相似度的方法
  20. 安装mysql以及遇到的问题解决

热门文章

  1. Java IO编程——File文件操作类
  2. 美团 iOS 端开源框架 Graver 在动态化上的探索与实践
  3. matlab 7遇到的错误 解决方法
  4. 设计模式(二十三)Interpreter模式
  5. Unity事件系统
  6. MySql悲观锁与乐观锁区别及使用场景
  7. AQS 入门
  8. js中几种继承实现
  9. [Spark]Spark-sql与hive连接配置
  10. Docker常见报错解决方法记录