一  进程相关介绍

1.1 进程的概念(process)

  • 进程就是正在运行的程序,它是操作系统中,资源分配的最小单位
  • 资源分配:分配的是cpu和内存等物理资源
  • 进程号是程的唯标识
  • 同—个程序执行两次之后是两个进程
  • 进程和进程之间的关系:数据彼此隔离,通过 socket通信

1.2 并行和并发

并发:一个cpu同一时间不停执行多个程序

并行:多个cpu同一时间不停执行多个程序

1.3 进程的调度方法

  1. 先来先服努fcfs( first come first server):先来的先执行
  2. 短作业优先算法:分配的cpu多,先把短的算完
  3. 时间片轮转算法:每一个任务就枘行一个时间片的时间.然后驯执行其他的
  4. 多级反馈队列算法

越是时间长的,cpu分配的资源越短,优先级靠后

越是时间短的,cpu分配的资源越多

1.4 进程三状态图

(1)就绪(Read)状态:只剩下CPU需要执行外,其他所有資源都已分配完毕称为就绪状态。

(2)执行(Running)状态:CPU开始执行该进程时称为执行状态。

(3)阻塞(Blocked)状态:由于等待某个事件发生而无法行时,便是阻塞状态,cpu执行其他进程.例如,等待I/O完成 input、申请缓中区不能满足等等。

1.5 同步 异步 /阻塞 非阻塞

场景在多任务当中

同步:必须等我这件事干完了,你在干,只有一条主线,就是同步

异步:没等我这件事情干完,你就在干了,有两条主线,就是异步

阻塞:比如代码有了 input,就是阻塞,必须要输入一个字符串,否则代码不往下执行

非阻塞:没有任何等待,正常代码往下执行

  • 同步阻塞:效率低,cpu利用不充分
  • 异步阻塞:比如 socketserver,可以同时连接多个,但是彼此都有recv
  • 同步非阻塞没有类似 input的代码,从上到下执行默认的正常情况代码
  • 异步非阻塞:效率是最高的,cpu过度充分,过度发热

二 python进程的相关操作

2.1 打印一个进程号

import os
from multiprocessing import Process
#获取子进程的ID(当前进程)
res = os.getpid()
print ("子进程是:",res)
#获取父进程id
res = os.getppid()
print ("父进程是:",res)

执行

[root@node10 python]# python3 test.py
子进程是: 3452
父进程是: 3294

2.2 进程的基本语法

import os
from multiprocessing import Process
#获取子进程的ID(当前进程)
res = os.getpid()
print ("子进程是:",res)
#获取父进程id
res = os.getppid()
print ("父进程是:",res)
def func():
print("1子进程id>>>:%s,父进程id>>>:%s" % (os.getpid(),os.getppid()) )
if __name__ == "__main__":
print("2子进程id>>>:%s,父进程id>>>:%s" % (os.getpid(),os.getppid()) )
# 创建子进程 target 是指定要完成的任务,后面接的是函数变量
p = Process(target=func)
# 调用子进程
p.start()
func()

执行

[root@node10 python]# python3 test.py
子进程是: 3468
父进程是: 3294
2子进程id>>>:3468,父进程id>>>:3294
1子进程id>>>:3468,父进程id>>>:3294
1子进程id>>>:3469,父进程id>>>:3468

2.3 带有参数的函数

import os
from multiprocessing import Process
def func():
for i in range(1,6):
print ("1子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
if __name__ == "__main__":
print ("2子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
p = Process(target=func)
#调用子进程
p.start()

执行

[root@node10 python]# python3 test.py
2子进程id:3488,父进程id:3294
1子进程id:3489,父进程id:3488
1子进程id:3489,父进程id:3488
1子进程id:3489,父进程id:3488
1子进程id:3489,父进程id:3488
1子进程id:3489,父进程id:3488

2先于1执行

import os
from multiprocessing import Process
def func():
for i in range(1,6):
print ("1子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
if __name__ == "__main__":
print ("2子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
p = Process(target=func)
#调用子进程
p.start()
n = 5
for i in range(1,n+1):
print ("*"*i)

执行

[root@node10 python]# python3 test.py
2子进程id:3494,父进程id:3294
*
**
***
****
*****
1子进程id:3495,父进程id:3494
1子进程id:3495,父进程id:3494
1子进程id:3495,父进程id:3494
1子进程id:3495,父进程id:3494
1子进程id:3495,父进程id:3494

带参数

import os
import time
from multiprocessing import Process
def func(n):
for i in range(1,n+1):
print ("1子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
if __name__ == "__main__":
print ("2子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
n = 5
p = Process(target=func,args=(n,))
#调用子进程
p.start()
for i in range(1,n+1):
print ("*"*i)

执行

[root@node10 python]# python3 test.py
2子进程id:3508,父进程id:3294
*
**
***
****
*****
1子进程id:3509,父进程id:3508
1子进程id:3509,父进程id:3508
1子进程id:3509,父进程id:3508
1子进程id:3509,父进程id:3508
1子进程id:3509,父进程id:3508

加延迟,即阻塞

import os
import time
from multiprocessing import Process
def func(n):
for i in range(1,n+1):
time.sleep(0.1)
print ("1子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
if __name__ == "__main__":
print ("2子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
n = 5
p = Process(target=func,args=(n,))
#调用子进程
p.start()
for i in range(1,n+1):
time.sleep(0.1)
print ("*"*i)

执行

[root@node10 python]# python3 test.py
2子进程id:3515,父进程id:3294
*
1子进程id:3516,父进程id:3515
**
1子进程id:3516,父进程id:3515
***
1子进程id:3516,父进程id:3515
****
1子进程id:3516,父进程id:3515
*****
1子进程id:3516,父进程id:3515

修改阻塞时间

import os
import time
from multiprocessing import Process
def func(n):
for i in range(1,n+1):
time.sleep(0.3)
print ("1子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))
if __name__ == "__main__":
print ("2子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid()))

      # 创建子进程,返回进程对象,如果有参数用args关键字参数进行指定
      # 对应的值是元组,参数赛到元组当中,按照传递次序排列

        n = 5
p = Process(target=func,args=(n,))
#调用子进程
p.start()
for i in range(1,n+1):
time.sleep(0.1)
print ("*"*i)

执行

2子进程id:3504,父进程id:3294
*
**
***
1子进程id:3505,父进程id:3504
****
*****
1子进程id:3505,父进程id:3504
1子进程id:3505,父进程id:3504
1子进程id:3505,父进程id:3504
1子进程id:3505,父进程id:3504

2.4 进程之间数据彼此隔离

import os
import time
from multiprocessing import Process
count = 99
def func():
global count
count += 1
print ("子进程id:%s"%(os.getpid()))
print (count)
if __name__ == "__main__":
p = Process(target=func)
p.start()
print ("主进程,count=",count)

执行

[root@node10 python]# python3 test.py
主进程,count= 99
子进程id:3527
100

主进程和子进程之间是隔离的,相当于是直接复制一份,不是直接延续主进程

import os
import time
from multiprocessing import Process
count = 99
def func():
global count
count += 1
print ("子进程id:%s"%(os.getpid()))
print (count)
if __name__ == "__main__":
p = Process(target=func)
p.start()
time.sleep(1)
print ("主进程,count=",count)

执行

[root@node10 python]# python3 test.py
子进程id:3533
100
主进程,count= 99

2.5 多进程之间的并发

在程序并发时,因为cpu的调度策略问题,不一定谁先执行,谁后执行,任务的执行,是资源抢占的过程

import os
import time
from multiprocessing import Process
def func():
print ("1子进程id:%s,父进程id:%s"%(os.getpid(),os.getppid())) if __name__ == "__main__":
for i in range(10):
Process(target=func).start()

执行

[root@node10 python]# python3 test.py
1子进程id:3538,父进程id:3537
1子进程id:3539,父进程id:3537
1子进程id:3540,父进程id:3537
1子进程id:3541,父进程id:3537
1子进程id:3542,父进程id:3537
1子进程id:3543,父进程id:3537
1子进程id:3544,父进程id:3537
1子进程id:3545,父进程id:3537
1子进程id:3546,父进程id:3537
1子进程id:3547,父进程id:3537

把i作为参数

import os
import time
from multiprocessing import Process
def func(i):
print("i=%s,1子进程id>>>:%s,父进程id>>>:%s" % (i,os.getpid(),os.getppid()) ) if __name__ == "__main__":
for i in range(10):
Process(target=func,args=(i,)).start()

执行

[root@node10 python]# python3 test.py
i=0,1子进程id>>>:3577,父进程id>>>:3576
i=1,1子进程id>>>:3578,父进程id>>>:3576
i=2,1子进程id>>>:3579,父进程id>>>:3576
i=3,1子进程id>>>:3580,父进程id>>>:3576
i=4,1子进程id>>>:3581,父进程id>>>:3576
i=5,1子进程id>>>:3582,父进程id>>>:3576
i=6,1子进程id>>>:3583,父进程id>>>:3576
i=7,1子进程id>>>:3584,父进程id>>>:3576
i=8,1子进程id>>>:3585,父进程id>>>:3576
i=9,1子进程id>>>:3 586,父进程id>>>:3576

2.6 子进程和父进程之间的关系

  • 通常情况下,父进程(主进程)速度执行稍块,但是不绝对,在父进程执行所有代码完毕之后,会默认等待所有子进程执行完毕,然后在彻底程序,为了方便进程的管理
  • 如果不等待,子进程会变成僵尸程序,在后台不停的占用内存和cpu,因为进程太多,一时找不到,并不容易.
import os
import time
from multiprocessing import Process
def func(args):
print("i=%s,1子进程id>>>:%s,父进程id>>>:%s" % (i,os.getpid(),os.getppid()) )
print("end,args= ",args) if __name__ == "__main__":
for i in range(10):
Process(target=func,args=(i,)).start()
print("主进程执行结束")

执行

[root@node10 python]# python3 test.py
i=0,1子进程id>>>:3591,父进程id>>>:3590
end,args= 0
i=1,1子进程id>>>:3592,父进程id>>>:3590
end,args= 1
i=2,1子进程id>>>:3593,父进程id>>>:3590
end,args= 2
i=3,1子进程id>>>:3594,父进程id>>>:3590
end,args= 3
i=4,1子进程id>>>:3595,父进程id>>>:3590
end,args= 4
i=5,1子进程id>>>:3596,父进程id>>>:3590
end,args= 5
i=6,1子进程id>>>:3597,父进程id>>>:3590
end,args= 6
i=7,1子进程id>>>:3598,父进程id>>>:3590
end,args= 7
主进程执行结束
i=8,1子进程id>>>:3599,父进程id>>>:3590
end,args= 8
i=9,1子进程id>

添加延迟阻塞

import os
import time
from multiprocessing import Process
def func(args):
print("i=%s,1子进程id>>>:%s,父进程id>>>:%s" % (i,os.getpid(),os.getppid()) )
time.sleep(0.3)
print("end,args= ",args) if __name__ == "__main__":
for i in range(10):
Process(target=func,args=(i,)).start()
print("主进程执行结束")

执行

[root@node10 python]# python3 test.py
i=0,1子进程id>>>:3616,父进程id>>>:3615
i=1,1子进程id>>>:3617,父进程id>>>:3615
i=2,1子进程id>>>:3618,父进程id>>>:3615
i=3,1子进程id>>>:3619,父进程id>>>:3615
i=4,1子进程id>>>:3620,父进程id>>>:3615
i=5,1子进程id>>>:3621,父进程id>>>:3615
i=6,1子进程id>>>:3622,父进程id>>>:3615
i=7,1子进程id>>>:3623,父进程id>>>:3615
主进程执行结束
i=8,1子进程id>>>:3624,父进程id>>>:3615
i=9,1子进程id>>>:3625,父进程id>>>:3615
end,args= 6
end,args= 0
end,args= 3
end,args= 4
end,args= 7
end,args= 1
end,args= 2
end,args= 5
end,args= 8
end,args= 9

三  join的基本使用

3.1 基本应用

等待有子进程执行完毕之后,主进程在向下执行;

import os
import time
from multiprocessing import Process
def func():
print("this is first thing") if __name__ == "__main__":
p = Process(target=func)
p.start()
print("This is second thing")

执行

[root@node10 python]# python3 test.py
This is second thing
this is first thing

first要先执行,使用阻塞延迟

import os
import time
from multiprocessing import Process
def func():
print("this is first thing") if __name__ == "__main__":
p = Process(target=func)
p.start()
time.sleep(0.2)
print("This is second thing")

执行

[root@node10 python]# python3 test.py
this is first thing
This is second thing

使用join

import os
import time
from multiprocessing import Process
def func():
print("this is first thing") if __name__ == "__main__":
p = Process(target=func)
p.start()
p.join() #自动加锁
print("This is second thing")

执行

[root@node10 python]# python3 test.py
this is first thing
This is second thing

3.2 __name__相关认知

打印__name__和__name__类型

print (__name__)
print (type(__name__))

执行

[root@node10 python]# python3 ceshi.py
__main__
<class 'str'>

3.3 调用自定义的模块

[root@node10 python]# vim mymoudle.py

print ("123 defined by myself")
a = 111222333

调用

import mymoudle
print (mymoudle.a)

执行

[root@node10 python]# python3 ceshi.py
123 defined by myself
111222333

或者

from  mymoudle import a
print (a)

执行

123 defined by myself
111222333

__name__:如果作为一个主文件执行,得到的时__main__,如果作为一个分模块导入,那么返回的时模块名称;是主进程,返回__main__ 不是主进程,返回模块名;

[root@node10 python]# vi mymoudle.py

print (__name__)

执行

[root@node10 python]# python3 mymoudle.py
__main__

当被调用时

import  mymoudle

再次执行

[root@node10 python]# python3 ceshi.py
mymoudle

由于教程使用的是windows,它所执行的是引用的模式,所以必须使用(if __name__ == "__main__)判断主进程,我这里使用的时centos系统,底层的实现方式是forks实现的,可以不添加,直接可以使用,来源:老男孩教育https://www.oldboyedu.com/

import os
import time
from multiprocessing import Process
def func():
print("this is first thing") #if __name__ == "__main__":
p = Process(target=func)
p.start()
p.join()
print("This is second thing")

执行

[root@node10 python]# python3 test.py
this is first thing
This is second thing

这样也不会报错,后面将直接使用linux的使用方式,如果有朋友使用windows系统做实验,请加上这个判断

3.4 多个子进程通过join加阻塞,可以和主进程进行同步控制

等子进程全部执行完毕之后,主进程在走

import os
import time
from multiprocessing import Process
def func(index):
print("第%s封邮件已经发送..."%(index)) for i in range(10):
p = Process(target = func,args = (i,))
p.start()
print ("发出第十封邮件...")

执行

[root@node10 python]# python3 test.py
第0封邮件已经发送...
第1封邮件已经发送...
第2封邮件已经发送...
第3封邮件已经发送...
第4封邮件已经发送...
第5封邮件已经发送...
第6封邮件已经发送...
第7封邮件已经发送...
发出第十封邮件...
第8封邮件已经发送...
第9封邮件已经发送...

使用列表,让每一个进程使用join

import os
import time
from multiprocessing import Process
def func(index):
print("第%s封邮件已经发送..."%(index)) lst = []
for i in range(10):
p = Process(target = func,args = (i,))
p.start()
lst.append(p)
for i in lst:
i.join()
print ("发出第十封邮件...")

执行

第0封邮件已经发送...
第1封邮件已经发送...
第2封邮件已经发送...
第3封邮件已经发送...
第4封邮件已经发送...
第5封邮件已经发送...
第6封邮件已经发送...
第7封邮件已经发送...
第8封邮件已经发送...
第9封邮件已经发送...
发出第十封邮件...

使用第二种方法创建进程

3.5 用自定义类的方式创建进程

必须继承父类Process,里面必须用run命名方法;

基本使用

import os
import time
from multiprocessing import Process
class MyProcess(Process):
def run(self):
pass
p = MyProcess()
p.start()
print ("主进程:{}".format(os.getpid()))

执行

[root@node10 python]# python3 test.py
主进程:3823

定义子进程

import os
import time
from multiprocessing import Process
class MyProcess(Process):
def run(self):
print("1子进程id>>>:%s,父进程id>>>:%s" % (os.getpid(),os.getppid()) )
p = MyProcess()
p.start()
print ("主进程:{}".format(os.getpid()))

执行

[root@node10 python]# python3 test.py
主进程:3823
1子进程id>>>:3824,父进程id>>>:3823

3.6 带参数的子进程函数

import os
import time
from multiprocessing import Process
class MyProcess(Process):
#这里需要传参,需要自己初始化,但是有需要调用父类方法
def __init__(self,arg):
#调用一下父类的构造方法来进行初始化
super().__init__()
#传入参数
self.arg = arg def run(self):
print("1子进程id>>>:%s,父进程id>>>:%s" % (os.getpid(),os.getppid()) )
print (self.arg)
lst = []
for i in range(10):
p = MyProcess("参数:%s"%(i))
p.start()
lst.append(p)
for i in lst:
i.join()
print ("最后执行子进程:{}".format(os.getpid()))

执行

[root@node10 python]# python3 test.py
1子进程id>>>:3845,父进程id>>>:3844
参数:0
1子进程id>>>:3846,父进程id>>>:3844
参数:1
1子进程id>>>:3847,父进程id>>>:3844
参数:2
1子进程id>>>:3848,父进程id>>>:3844
参数:3
1子进程id>>>:3849,父进程id>>>:3844
参数:4
1子进程id>>>:3850,父进程id>>>:3844
参数:5
1子进程id>>>:3851,父进程id>>>:3844
参数:6
1子进程id>>>:3852,父进程id>>>:3844
参数:7
1子进程id>>>:3853,父进程id>>>:3844
参数:8
1子进程id>>>:3854,父进程id>>>:3844
参数:9
最后执行子进程:3844

040.Python进程和Join的更多相关文章

  1. python 进程介绍 进程简单使用 join 验证空间隔离

    一.多道程序设计技术(详情参考:https://www.cnblogs.com/clschao/articles/9613464.html) 所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行 ...

  2. python——进程基础

    我们现在都知道python的多线程是个坑了,那么多进程在这个时候就变得很必要了.多进程实现了多CPU的利用,效率简直棒棒哒~~~ 拥有一个多进程程序: #!/usr/bin/env python #- ...

  3. python进程、线程、协程(转载)

    python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资 ...

  4. Python进程、线程、协程详解

    进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. ...

  5. python——进程、线程、协程

    Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env pytho ...

  6. Python 进程之间共享数据

    最近遇到多进程共享数据的问题,到网上查了有几篇博客写的蛮好的,记录下来方便以后查看. 一.Python multiprocessing 跨进程对象共享  在mp库当中,跨进程对象共享有三种方式,第一种 ...

  7. python进阶:Python进程、线程、队列、生产者/消费者模式、协程

    一.进程和线程的基本理解 1.进程 程序是由指令和数据组成的,编译为二进制格式后在硬盘存储,程序启动的过程是将二进制数据加载进内存,这个启动了的程序就称作进程(可简单理解为进行中的程序).例如打开一个 ...

  8. python进程、多进程

    进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当 ...

  9. python2.0 s12 day8 _ python线程&python进程

    1.进程.与线程区别2.cpu运行原理3.python GIL全局解释器锁4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 6.q ...

随机推荐

  1. BUAA_OO_2020_第二单元总结

    BUAA_OO_2020_第二单元总结 第一次 设计策略 本次作业采用生产者.消费者模式设计,大致框架如图所示: 生产者:输入线程 消费者:电梯线程 托盘:Dispatcher调度器 线程安全方面,调 ...

  2. 记一次metasploitable2内网渗透之1524端口

    0x01.漏洞 许多攻击脚本将安装一个后门SHELL于这个端口,尤其是针对SUN系统中Sendmail和RPC服务漏洞的脚本.如果刚安装了防火墙就看到在这个端口上的连接企图,很可能是上述原因.可以试试 ...

  3. 记一次metasploitable2内网渗透之21,22,23,25端口爆破

    Hydra是一款非常强大的暴力破解工具,它是由著名的黑客组织THC开发的一款开源暴力破解工具.Hydra是一个验证性质的工具,主要目的是:展示安全研究人员从远程获取一个系统认证权限. 目前该工具支持以 ...

  4. 后端Spring Boot+前端Android交互+MySQL增删查改

    2021.1.27 更新 已更新新版本博客,更新内容很多,因此新开了一篇博客,戳这里. 1 概述 使用spring boot作为后端框架与Android端配合mysql进行基本的交互,包含了最基本的增 ...

  5. 黑马 - poi Excel

    3.poi入门操作 3.1 搭建环境 1 <dependency> 2 <groupId>org.apache.poi</groupId> 3 <artifa ...

  6. C#入门到精通系列课程——第2章编写C#程序

    ◆本章内容 (1)熟悉Visual Studio 2017开发环境 (2)编写第一个C#程序 (3)C#程序结构预览 (4)程序编写规范 (5)难点解答 ◆本章简述 要学习C#编程,必然要熟悉C#程序 ...

  7. Word 查找和替换字符串方法

    因为项目需要通过word模板替换字符串 ,来让用户下载word, 就在网上找了找word查找替换字符串的库或方法,基本上不是收费,就是无实现,或者方法局限性太大 .docx 是通过xml来存储文字和其 ...

  8. 开源Influxdb2高性能客户端

    前言 最近我在了解时序数据库Influxdb 2.x版本,体验一翻之后,感觉官方的出品的.net客户端还有很多优化的地方,于是闭关几天,不吃不喝,将老夫多年练就的高性能网络通讯与高性能Buffer操作 ...

  9. Tomcat部署环境

    环境搭建:程序文件(开发人员),相关的软件(web服务器,应用服务器,数据服务器),硬件(服务器设备上),网络环境. 文档:部署文档说明书(操作系统,硬件配置,服务器软件及相关..) 下面举个列子,考 ...

  10. vue.js中$emit的理解

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...