创建进程

    在python中提供了一个multiprocessing模块可以帮助我们使用多进程解决问题。在multiprocessing
模块中有一个类Process。
    from multiprocessing import Process

'''
group=None, 为日后开发新功能准备
target=None, 目标任务
name=None, 进程的姓名
args=(), 目标任务需要的位置参数
kwargs={}, 目标任务需要的字典参数
daemon=None):默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
'''
#方法介绍
p.start()#开启进程,使用run()方法
p.run()#进程启动时运行的方法是它去调用target指定的目标
p.terminate()#强制终止进程,不会进行清理操作
p.is_alive()#判断进程是否存活
p.join([timeout])#让在join方法之后的进程等待,直到p进程运行结束 """
强调:不同的操作系统创建进程的要求不一样
在windows中创建进程是以导入模块的方式进行 所以创建进程的代码必须写在__main__子代码中
否则会直接报错 因为在无限制创建进程
在linux和mac中创建进程是直接拷贝一份源代码然后执行 不需要写在__main__子代码中
"""

第一种方法

    from multiprocessing import Process
import time def test():
print('=======>')
time.sleep(3)
print('=======>') def test1(name):
print(f'{name}')
time.sleep(3)
print('=======>') if __name__ == '__main__':
p = Process(target=test)
# p = Process(target=test1, args=('春游去动物园',))
p.start()
print('主')

第二种方法

    from multiprocessing import Process

    class Test(Process):
def __init__(self,name):
super().__init__()
self.name = name def run(self):
print(self.name) if __name__ == '__main__':
p = Test('test')
p.start()
print('主')
#自定义类主要是改写他的run()方法,run()方法在调用start()方法时一定会被调用

join

'''join让主进程等待子进程结束之后,再执行主进程。'''

    from multiprocessing import Process
import time
def task(name):
print(f"{name} is running")
time.sleep(2)
print(f"{name} is gone")
if __name__ == "__main__":
p = Process(target=task, args=("春游去动物园",)) # 创建一个进程对象
p.start()
# p.join()
print(111)
print("主开始") 111
主开始
春游去动物园 is running
春游去动物园 is gone from multiprocessing import Process
import time
def task(name):
print(f"{name} is running")
time.sleep(2)
print(f"{name} is gone")
if __name__ == "__main__":
p = Process(target=task, args=("春游去动物园",)) # 创建一个进程对象
p.start()
p.join()
print(111)
print("主开始") 春游去动物园 is running
春游去动物园 is gone
111
主开始
'''一般而言,主程序中如果单为一句print,则优先执行print语句(如果执行语句够多,则可见子进程执行)'''

    from multiprocessing import Process
import time def task(name):
print(f"{name} is running")
time.sleep(2)
print(f"{name} is gone") if __name__ == "__main__":
p = Process(target=task,args=("春游去动物园",)) # 创建一个进程对象
p.start()
# p.join()
print(111)
time.sleep(0.5)
print("主开始") 111
春游去动物园 is running
主开始
春游去动物园 is gone
'''如果程序中有连续多个join函数,则只有最先的join是起作用的'''
from multiprocessing import Process
import time def task(name,sec):
print(f"{name} is running")
time.sleep(sec)
print(f"{name} is gone") if __name__ == "__main__":
start_time = time.time()
p = Process(target=task,args=("常",3)) # 创建一个进程对象
p1 = Process(target=task,args=("辛",5)) # 创建一个进程对象
p2 = Process(target=task,args=("王",1)) # 创建一个进程对象 p.start()
p1.start()
p2.start() # join只针对主进程,如果join下面多次join他是不阻塞的
p.join()
p1.join()
p2.join() print(f"主{time.time()-start_time}") 辛 is running
常 is running
王 is running
王 is gone
常 is gone
辛 is gone
主5.103694438934326 # 注:如果不是连续多个,比如这样:
from multiprocessing import Process
import time def task(name,sec):
print(f"{name} is running")
time.sleep(sec)
print(f"{name} is gone") if __name__ == "__main__":
start_time = time.time()
p = Process(target=task,args=("常",3)) # 创建一个进程对象
p1 = Process(target=task,args=("辛",5)) # 创建一个进程对象
p2 = Process(target=task,args=("王",1)) # 创建一个进程对象 p.start()
p.join()
p1.start()
p1.join()
p2.start()
p2.join() print(f"主{time.time()-start_time}") 常 is running
常 is gone
辛 is running
辛 is gone
王 is running
王 is gone
主9.267089128494263
# 这样就会先执行p进程,再执行p1进程,再执行p2进程

进程间数据默认隔离

    from multiprocessing import Process

    a=100
def test():
global a
a=50
print(a) # 50 if __name__ == '__main__':
p = Process(target=test)
p.start()
print(a) # 100 100
50

进程对象属性和方法

查看进程号

    '''第一种current_process函数'''
from multiprocessing import Process,current_process
a=100
def test():
global a
a=50
print(a) # 50
if __name__ == '__main__':
p = Process(target=test)
p.start()
print(current_process()) # 获取进程的名称 <_MainProcess name='MainProcess' parent=None started>
print(current_process().pid) # 获取进程的id 8560
print(a) # 100 '''第二种os模块'''
import os
from multiprocessing import Process,current_process
a=100
def test():
global a
a=50
print(a) # 50
if __name__ == '__main__':
p = Process(target=test)
p.start()
print(os.getpid()) # 9748 获取当前进程的进程号
print(os.getppid()) # 5220 获取当前进程的父进程号
print(a) # 100 os.getpid() # 获取当前进程的进程号
os.getppid() # 获取当前进程的父进程号

杀死子进程

    terminate():不管任务是否完成,立即终止子进程
from multiprocessing import Process,current_process
import time
a=100
def test():
global a
time.sleep(3)
a=50
print(a)
if __name__ == '__main__':
p = Process(target=test)
p.start()
p.terminate()
print(a)
100

判断子进程是否存活

    is_alive():判断进程子进程是否还在活着
from multiprocessing import Process,current_process
import time
a=100
def test():
global a
time.sleep(3)
a=50
print(a)
if __name__ == '__main__':
p = Process(target=test)
p.start()
print(p.is_alive()) # True
p.terminate() # 杀死进程
time.sleep(0.5)
print(p.is_alive()) # False

僵尸进程与孤儿进程

僵尸进程

  僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子
进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
'''
僵死进程:子进程退出后,会将该进程的重型资源释放掉(cpu,内存,打开的文件),子进程的进
程描述符仍然保存在系统中,比如pid。
'''
所有的子进程在运行结束之后都会变成僵尸进程(死了没死透)
程序正常结束才会产生僵尸进程,如果强制关闭父进程,操作系统会把父进程已经运行结束的子进程全部
删除,也就不会产生僵尸进程了。
僵尸进程的危害:
系统的pid号是有限的,僵尸进程保留的信息如果一直不被释放,一直累计会导致没有可用的pid号而
导致系统不能产生新的进程

孤儿进程

   孤儿进程(无害):一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿
进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
'''
子进程存活着 父进程意外死亡
子进程会被操作系统自动接管(儿童福利院)
'''

守护进程

    正常情况下,主进程默认等待子进程调用结束之后结束
守护进程在主进程执行代码结束后,自动终止
"""
守护即死活全部参考守护的对象
对象死立刻死
"""
主进程代码运行完毕,守护进程就会结束
from multiprocessing import Process
import os, time def task():
print("进程%s开启" % os.getpid())
time.sleep(10)
print("进程%s结束" % os.getpid()) if __name__ == '__main__':
p = Process(target=task,daemon=True) # 在创建进程时也可以设置daemon,True为开启守护进程,默认为False。
#p.daemon = True # 这一行代码会把子进程变成守护代码,主进程运行完,子进程也就运行完了,不会打印进程结束的那行代码
p.start()
print("主:%s" % os.getpid())
time.sleep(3) 主:6812
进程10096开启

互斥锁

互斥锁的概念

    互斥锁: 对共享数据进行锁定,保证同一时刻只能有一个线程去操作。

    注意:
互斥锁是多个线程一起去抢,抢到锁的线程先执行,没有抢到锁的线程需要等待,等互斥锁使用完释放
后,其它等待的线程再去抢这个锁。 互斥锁的意思就是互相排斥,我们可以把多个进程比喻多个人,互斥锁的工作原理就是多个人去争抢共同
的一个资源:如多个人要上同一个卫生间,一个人抢到卫生间后上一把锁,其他人都有外面等着,等到这个人
完成后解锁后,其他人又可以去争夺。所以互斥锁的原题,就是把某一功能并发改串行,虽然降低了效率,但
保证了数据安全不错乱。
"""
锁相关知识
行锁:针对行数据加锁 同一时间只能一个人操作
表锁:针对表数据加锁 同一时间只能一个人操作
锁的应用范围很广 但是核心都是为了保证数据的安全!!!
"""

互斥锁的使用

    from multiprocessing import Process,Lock
# 创建锁
mutex = Lock() # 上锁
mutex.acquire() ...这里编写代码能保证同一时刻只能有一个线程去操作, 对共享数据进行锁定... # 释放锁
mutex.release() 注意点:
acquire和release方法之间的代码同一时刻只能有一个线程去操作
如果在调用acquire方法的时候 其他线程已经使用了这个互斥锁,那么此时acquire方法会堵塞,直到
这个互斥锁释放后才能再次上锁。

互斥锁与join()的区别

    互斥锁与join()的区别:
大前提:二者的原理都是一样,都是将并发变成串行,从而保证有序 区别一:join是按照人为指定的顺序执行,而互斥锁是所有进程平等地竞争,谁先抢到谁先执行。 区别二:互斥锁可以让一部分代码(修改共享数据的代码)串行,而join只能将代码整体串行。

抢票小案例

    # db.json文件中的内容为{"count": 100}
from multiprocessing import Process, Lock
import json, time
import random def search(name):
dic = json.load(open('db.json', 'r', encoding='utf-8'))
time.sleep(random.randint(0, 2)) # 模拟网络延迟
print('%s查到剩余的票数为%s张' % (name, dic['count'])) def get(name):
dic = json.load(open('db.json', 'r', encoding='utf-8'))
time.sleep(0.3) # 模拟网络延迟
if dic['count'] > 0:
time.sleep(0.1) # 模拟网络延迟
print('%s成功买到了剩下的第%s票' % (name, dic['count']))
dic['count'] -= 1
json.dump(dic, open('db.json', 'w', encoding='utf-8')) def rob_ticket(name, lock):
search(name)
with lock: # 相当于获得了lock.acquire(),执行代码体完,自动执行lock.release()
get(name) if __name__ == '__main__':
lock = Lock()
for i in range(10):
name = '路人%s' % i
p = Process(target=rob_ticket, args=(name, lock))
p.start() 执行结果:
路人0查到剩余的票数为5张
路人1查到剩余的票数为5张
路人8查到剩余的票数为5张
路人7查到剩余的票数为5张
路人9查到剩余的票数为5张
路人0成功买到了剩下的第5票
路人1成功买到了剩下的第4票
路人2查到剩余的票数为5张
路人4查到剩余的票数为5张
路人3查到剩余的票数为5张
路人6查到剩余的票数为5张
路人8成功买到了剩下的第3票
路人7成功买到了剩下的第2票
路人5查到剩余的票数为5张
路人9成功买到了剩下的第1票

创建进程,join方法,进程对象相关属性和方法,僵尸进程和孤儿进程,守护进程,互斥锁的更多相关文章

  1. vue第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件)

    第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件) #课程目标 掌握vue实例的相关属性和方法的含义和使用 了解vue的数据响应原理 熟悉创建组件,了解全局 ...

  2. Javascript常用对象的属性和方法

    javascript为我们提供了一些非常有用的常用内部对象和方法.用户不需要用脚本来实现这些功能.这正是基于对象编程的真正目的. 在javascript提供了string(字符串).math(数值计算 ...

  3. 理解Python中的类对象、实例对象、属性、方法

    class Animal(object): # 类对象 age = 0 # 公有类属性 __like = None # 私有类属性 def __init__(self): # 魔法方法 self.na ...

  4. HTML DOM对象的属性和方法

    HTML DOM对象的属性和方法 HTML DOM 对象有几种类型: 1.Document 类型 在浏览器中,Document 对象表示整个 HTML 文档. 1.1属性 引用文档的子节点 docum ...

  5. String对象的属性和方法

    String对象的属性和方法   创建字符串的两种方法: 1.直接量:var str = ""; 2.字符串对象创建: new String(""); Stri ...

  6. HTML DOM对象的属性和方法介绍(原生JS方法)

    HTML DOM对象的属性和方法介绍 DOM 是 Document Object Model(文档对象模型)的缩写. DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口), ...

  7. HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次)

    HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次) 一.总结 一句话总结:目录就是测试题 1.document取得元素(get element)的方式有哪几种? 解答:四种,分别是id ...

  8. javascript基本属性访问对象的属性和方法

    var myName = "Shelley"; //字符串基本类型 alert(myName.length);  //隐式创建String对象,数值与myName相同,并执行len ...

  9. JS中的RegExp对象常用属性和方法

    JavaScript提供了一个RegExp对象来完成有关正则表达式的操作和功能,每一条正则表达式模式对应一个RegExp实例.有两种方式可以创建RegExp对象的实例. 使用RegExp的显式构造函数 ...

随机推荐

  1. 什么是 spring?

    Spring 是个 java 企业级应用的开源开发框架.Spring 主要用来开发 Java 应用, 但是有些扩展是针对构建 J2EE 平台的 web 应用.Spring 框架目标是简化 Java 企 ...

  2. 学习Kvm(三)

    虚拟化(将一个物理硬件平台虚拟成多个) vmware(模拟出一堆硬件设备,每一个硬件设备都是独立平台) 虚拟化要解决的问题(硬件之上的OS,有用户空间.内核空间:vmware虚拟机所模拟出的多个硬件平 ...

  3. docker学习-01-安装docker

    [root@localhost firstDocker]# cat /etc/centos-release CentOS Linux release 7.6.1810 (Core) [root@loc ...

  4. 经历了源码的痛苦,掌握DRF的核心序列化器

    目录 DRF的核心--序列化器 序列化器 什么是序列化和反序列化? 序列化 序列化demo 字段类型 字段参数 序列化自定制返回字段 方法一:在序列化类(serializers.py)中写 方法二:在 ...

  5. ACM - 最短路 - AcWing 849 Dijkstra求最短路 I

    AcWing 849 Dijkstra求最短路 I 题解 以此题为例介绍一下图论中的最短路算法.先让我们考虑以下问题: 给定一个 \(n\) 个点 \(m\) 条边的有向图(无向图),图中可能存在重边 ...

  6. 小程序的初次遇见,使用mpvue搭建模板

    由于公司业务需求的需要,在这一周需要开发小程序,加急看了下小程序的文档,发现用其原生来编写程序不是很顺手,公司前端用的技术栈是vue, 询问了谷哥和度娘发现大部分推荐了 wepy和 mpvue,对比了 ...

  7. mysql的下载和安装详细教程(windows)

    Windows下安装MySQL详细教程 1.安装包下载    2.安装教程 (1)配置环境变量 (2)生成data文件 (3)安装MySQL (4)启动服务 (5)登录MySQL (6)查询用户密码 ...

  8. java多线程的状态转换以及基本操作

    1. 新建线程 一个java程序从main()方法开始执行,然后按照既定的代码逻辑执行,看似没有其他线程参与,但实际上java程序天生就是一个多线程程序,包含了:(1)分发处理发送给给JVM信号的线程 ...

  9. Taro开发微信小程序遇到的问题和解决方法

    1.scroll-view 置顶, 给设置scroll-top为0无效问题? 解决方案: 不触发置顶问题,需要给scroll-top一个设置接近0的随机数,Math.random() 2.scroll ...

  10. FastAPI(六十九)实战开发《在线课程学习系统》接口开发--修改密码

    之前我们分享了FastAPI(六十八)实战开发<在线课程学习系统>接口开发--用户 个人信息接口开发.这次我们去分享实战开发<在线课程学习系统>接口开发--修改密码 我们梳理一 ...