python进程学习心得

进程

1. 什么是进程

一个学校里面有很多不同的学院,他们都是相互独立,教学内容也不一样,但都是属于学校。
程序运行的进程为父进程,在父进程下创建的都为子进程,父进程结束,则所有的子进程也会结束。
子进程直接相互独立不干扰,都有相对应的进程号,在资源方面不共享,相对进程资源管理更加简易,但是会占用CPU内存。

2. Linux下命令符对进程的操作

2.1 ps 查看当前运行的进程
        ps -a 在终端上显示所有用户的进程,包括其他用户
        ps -u 查看进程的详细信息状态
        ps -显示没有终端控制的进程
        ps -j 显示作业控制的相关进程,可查看父进程
        ppid 为父进程id
        pid 为进程id
        kill发出指令要求进程死亡
        sudo kill pid 以超级用户权限杀死进程
        kill -9 pid 强制杀死

3. 进程的状态

死亡态, 运行态,等待(阻塞)态,就绪态,新建


进程.png

4 创建进程

首先导入multiprocessing模块

p=multiprocessing.Process(group=None,target=None,name=None,args=(),kwar
s={},,daemon=None)

import multiprocessing
def course(str):
      print(str)
# 启动进程
str = "hello world"
p1 = multiprocessing.Process(target=course, args=(str, ))
# 启动进程
p1.start()

4.1 创建进程的参数

group:指定进程组,大多数情况下用不到

target:如果传递了函数的引用,可以任务这个子进程就执行这里的代码

name:给进程设定一个名字,可以不设定

args:给target指定的函数传递的参数,以元组的方式传递

kwargs:给target指定的函数传递命名参数

daemon:是否以守护进程运行,True 或False

4.2 进程的方法

start()开始进程

is_alive()判断线程是否存活

join([timeout])是否等待子进程执行结束,或者等待多少时间

import multiprocessing
def course(str):
        print(str)
# 启动进程
str = "hello world"
p1 = multiprocessing.Process(target=course, args=(str, ))
# 判读进程是否存活
print("线程未启动时,是否存活:", p1.is_alive())
# 启动进程
p1.start()
# 线程已开始
print("线程启动时,是否存活:", p1.is_alive())

线程未启动时,是否存活: False
线程启动时,是否存活: True
hello world

5. 线程和进程的区别

5.1 线程

线程是一个进程下,同时实现多个任务,共享全局变量,因为是在一个进程下,所以占用系统资源小,容易造成资源抢夺

5.2 进程

进程是相互独立的存在,每个进程都有对应的进程号,相当于再开辟出一个内存空间进行运行,进程之间全局变量不共享。多进程相对多线程更加消耗系统资源,但是在资源上能够更好的处理

6.进程池

6.1 进程池的作用

进程池可以消耗最小的系统内存和时间处理大量的系统操作.

如果没有线程池。在需要处理上百或者上千条线程则需要同时创建成百上千个线程,而这是不太现实的,即使能够创建,也会浪费大量的时间在创建线程,消灭进程中。

使用线程池处理大量并发线程,可以使用最小的系统占用内存,处理更多的线程,在创建的线程池的线程中,不断循环使用,而不关闭线程,这样可以做到,反复利用,加快运行效率,也避免了同时创建大量的线程导致的系统崩溃

6.2 创建进程池

首先导入multiprocessing.Pool()

apply_async(方法(参数))线程池创建线程方法

close()关闭线程池,不再创建线程,但是会将之前的线程运行结束

join()主进程等待子进程结束后再结束,会堵塞至子进程结束,必须写在close()或terminate()后使用,如果不使用join()主进程会直接结束。如:亲子赛跑,父亲先到达终点后,会继续前进然后停止,使用了join后父亲会在终点处等待孩子们都到达终点后再结束

import multiprocessing, time, os
def course(str):
        # 进程开始时间
        start_time = time.time()
        print("进程: %s,我的进程号为:%d , 我的父进程号为:%d" % (str, os.getpid(), os.getppid()))
        # 结束时间
        end_time = time.time()
        print("进程%s, 消耗时间:%.5f," % (str, (end_time - start_time)))
        # 让进程休眠0.5s再运行
        time.sleep(0.5)
        

list_str = ["python", "c", "java"]
# 创建进程池, 数量为两个
po = multiprocessing.Pool(3)
for str in list_str:
   # 向进程池添加任务
   po.apply_async(course, (str,))
   print("hello")
# 关闭进程池
po.close()
# 父进程等待子进程结束后结束
po.join()

hello
hello
hello
进程: python,我的进程号为:6412 , 我的父进程号为:6411
进程python, 消耗时间:0.00007,
进程: c,我的进程号为:6413 , 我的父进程号为:6411
进程c, 消耗时间:0.00011,
进程: java,我的进程号为:6414 , 我的父进程号为:6411
进程java, 消耗时间:0.00005,

如果不添加join()方法,则效果如下

hello
hello
hello

6.3进程间的通信

6.3.1 为什么需要进程间的通信

进程中全局变量是不同享的,无法进程沟通,导致对应数据无法传输。

进程之间相互独立运行,但是也需要进行沟通通信合作,如:QQ和QQ音乐两个进程之间的通信。

进程之间的通信方便了资源的处理,有利于进程之间的运行

7.Queue队列

  • multiprocessing.Queue()创建消息队列
    部分mac电脑必须multiprocessing.Manger().Queue()创建进程池的消息队列,在进程池中使用消息队列必须使用此方法,否则会抛出异常
  • from queue import Queue 系统自带消息队列模块不能进行线程之间的通信,属于各自线程私有
  • put(msg, [block[,timeout]])存入消息, 使用默认block值为True,timeout设置如果消息队列已满,经过多久时间后再次尝试,如果时间到了没有空位则会抛出异常Queue,Full。如果未设置时间,队列为满则会出现堵塞状态,一直到消息队列出现空位为止。block设置为False,如果消息队列已满则会立即抛出异常Queue.Full
  • get()释放消息
  • qsize()或者当前队列的消息数量
  • empty() 如果队列为空则返回False, 反之则返回True。系统在添加队列事有一定延迟,最后在添加完后睡眠0.5s左右,以保证empty()能够正常判读
  • full() 如果队列为空则返回True, 反之则返回False
  • put_nowait() 如果消息队列已满,则抛出异常,Queue.Full ,相当于put(msg,False)
import multiprocessing, time
# 创建消息队列,为三条
q = multiprocessing.Queue(3)
# 存入消息
q.put('我是第一条消息')
q.put('我是第二条消息')
q.put('我是第三条消息')
time.sleep(0.5)
try:
    q.put("我是第四条消息", False)
except BaseException :
    print("消息队列已满")
# 判断消息队列是否为空
print("empty", q.empty())
print("full", q.full())
# 打印当前消息数量
print("当前一共有:%d条消息" %q.qsize())
print(q.get())
print(q.get())
print(q.get())
# 打印当前消息数量
print("当前一共有:%d条消息" %q.qsize())
print("empty", q.empty())
print("full", q.full())

消息队列已满
empty False
full True
当前一共有:3条消息
我是第一条消息
我是第二条消息
我是第三条消息
当前一共有:0条消息
empty True
full False

本文还有很多不足,如有更好的意见或者有什么遗漏欢迎大家补充,第一次用MarkDown编辑器,可能在观赏上有点不太美观,望谅解。会持续更新自己的学习心得,大家可以一起来交流

你可能感兴趣的:(python进程学习心得)