python进程学习

Posted grave-seven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python进程学习相关的知识,希望对你有一定的参考价值。

学习知识点:

  1.知识点叫什么

  2.知识点用在哪

  3.知识如何实现

 

一. 进程

  1.进程是什么

  进程是cpu分配资源的最小单位

  理解:在QQ这个进程里,传输一段文字开启一个线程,传输语音又开启一个线程。所以运行某个软件相当于开启了一个进程。而在这个进程里,有多个功能来支持QQ正常运行,这些功能又各自占了一条线程。

  一个进程管理着多个线程。(一个进程至少带一个线程)

  线程和进程的:

    1.单进程单线程:一个人在一个桌子上吃饭

    2.单进程多线程:多个人在一个桌子上吃饭

    3.多进程单线程:多个人每个人在自己桌子上吃饭

技术分享图片

 

  2.进程的状态

  技术分享图片

  状态分析:就绪态(运行的条件都已经慢去)执行态(zpu正在执行其他的功能)等待态(等待某些条件满足,例如一个程序sleep了,此时就处于等待态)

 

  3.进程的作用

  实现多个任务同时运行,跟多线程功能基本一致。

  

技术分享图片
 1 import multiprocessing  # 导包
 2 import time
 3 
 4 
 5 def test1():
 6     while True:
 7         print("1------")
 8         time.sleep(1)
 9 
10 
11 def test2():
12     while True:
13         print("2------")
14         time.sleep(1)
15 
16 
17 def main():
18     # 创建进程,跟创建多线程一致
19     t1 = multiprocessing.Process(target=test1)
20     t2 = multiprocessing.Process(target=test2)
21 
22     # 开启进程
23     t1.start()
24     t2.start()
25 
26 
27 if __name__ == __main__:
28     main()
View Code

 

  4.主进程与子进程

  子进程开启会复制主进程一样的代码

 

  5.进程和线程的区别

    1.进程浪费资源较大,而且一段代码进程执行的速度明显比线程慢。

    2.进程的资源相互独立不共享,如需通信需要借助一些方法。 线程资源是共享的,但是也有bug,需要加锁。

    3.进程稳定性好,一个任务挂了,有可能整个进程都挂了,但不会影响其他进程。

 

二. 进程命令进程

  1.查看进程

  

ps -aux

  技术分享图片

htop

  技术分享图片

top

  技术分享图片

  2.杀死进程

  

kill pid名
kill -9 pid名

  关于这个命令,之前询问别人其之间的区别,有人讲kill -9 pid 是删除所有与进程相关的,我的疑惑就来了,既然进程之间不相互影响,那么删的是什么相关的呢?一个杀死进程的命令,除了进程还能杀死什么?

  于是,我上网查了下,再别人的博客下得到了答案:一般不建议使用 kill -9 pid

  kill(默认是-15)的真实含义是, 向进程发送信息,而不是杀死进程。 kill  1234  是向进程1234发送一个SIGTERM信号,有时候 kill 1234 并不能结束这个进程,用kill -9 1234 是真的kill了, kill -9  1234是向1234发送SIGKILL信号

  两句命令的区别:SIGNKILL(9) 的效果是立即杀死进程. 该信号不能被阻塞, 处理和忽略。 SIGNTERM(15) 的效果是正常退出进程,退出前可以被阻塞或回调处理。并且它是Linux缺省的程序中断信号。

  一句话, kill是温柔地杀, kill -9是霸气地杀

 

三. 进程的相关知识

  1.pid获取

技术分享图片
 1 import multiprocessing
 2 import time
 3 import os
 4 
 5 
 6 def test1():
 7     while True:
 8         print("1-----")
 9         time.sleep(1)
10         print("子进程1",os.getpid())  # 获取当前进程号
11         print("主进程",os.getppid())  # 获取主进程的进程号
12 
13 
14 def test2():
15     while True:
16         print("2-----")
17         time.sleep(1)
18         print("子进程2",os.getpid())
19         print("主进程",os.getppid())
20 
21 
22 def main():
23     # 创建进程
24     t1 = multiprocessing.Process(target=test1)
25     t2 = multiprocessing.Process(target=test2)
26 
27     # 开启进程
28     t1.start()
29     t2.start()
30 
31     print("主进程", os.getpid())  # 获取主进程的进程号
32 
33 
34 if __name__ == __main__:
35     main()
查看进程pid
主进程 7904
1-----
2-----
子进程1 7560
主进程 7904
1-----
子进程2 6136
主进程 7904
2-----
子进程1 7560
主进程 7904
1-----
子进程2 6136
主进程 7904
2-----
子进程1 7560

 

  2.子进程中不能使用input()函数,主进程会等到子进程结束而结束,线程是用来执行代码的,进程使用分配资源的,子进程会复制主进程的资源数据,进程之间的数据不共享,进程的执行时无序的。

  3.传参

  技术分享图片

 

四. 进程与线程的对比

  1.进程是分配资源的单位,线程是程序调度的单位

  2.进程运行必定有一个主线程运行

  3.全局变量:线程共享全局变量,进程不共享全局变量。

  技术分享图片

  4.加深理解进程与线程的图片

  技术分享图片创建

 

五. 进程间的通讯

  1.使用的技术:Queue队列

  2.作用:让进程之间可以通讯  

技术分享图片
import queue


# 先进先出
q = queue.Queue()
q.put(1)
q.put(2)
q.put(3)


print(q.get())
print(q.get())
print(q.get())

# 后进先出
q = queue.LifoQueue()
q.put(1)
q.put(2)
q.put(3)


print(q.get())
print(q.get())
print(q.get())


# 存储数据时可设置优先级的队列

q = queue.PriorityQueue()
# put进入一个元祖,元祖的第一个元素是优先级,数字越小优先级越高
q.put((20, a))
q.put((10, b))
q.put((30, c))


print(q.get())
print(q.get())
print(q.get())
queue的用法

  3.使用方式

  创建队列放入数据

  技术分享图片

  获取数据

  技术分享图片

  

技术分享图片
# 定义一个队列
import multiprocessing

# 定义一个队列
# 队列的作用存取数据
# 队列中的数据取完就没了
# 队列中先存先取
import time

queue = multiprocessing.Queue(3)

# 存数据
queue.put_nowait("abc")
queue.put_nowait("abc")
queue.put_nowait("abc")
# queue.put_nowait("abc")

# print(queue.empty())  # 空是有bug

time.sleep(1)

#
print(queue.get_nowait())
print(queue.get_nowait())
# print(queue.get_nowait())
print(queue.empty())  # 空是有bug
# print(queue.get_nowait())
BUG代码不要用

  4.案例:一个进程读一个进程写,在进程创建前创建进程队列 

技术分享图片
import multiprocessing
import queue
import time


def write(queue):  # 记得传参数
    """写数据的函数"""
    # 通过循环去写数据
    for temp in range(10):
        queue.put(temp)
        print(temp)
    time.sleep(1)


def read(queue):
    """定义一个读的函数"""
    data_list = []
     # 通过循环去读数据
    while True:
        if queue.empty():
            break
        data_list.append(queue.get())
    print(data_list)


def main():
    # 定义一个进程队列

    queue = multiprocessing.Queue()  # 这个说明没有限制机器性能

    # 创建两个进程
    process_write = multiprocessing.Process(target=write, args=(queue,))
    process_read = multiprocessing.Process(target=read, args=(queue,))

    # 开启线程
    process_write.start()
    process_write.join()  # 控制写完读,保证有数据在读
    process_read.start()


if __name__ == __main__:
    main()
View Code
打印结果:先顺序打印0-9 ,停顿1S,在打印0-9的列表。
0
1
2
3
4
5
6
7
8
9
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  

六. 进程池

  1.什么是进程池

  python中,进程池内部会维护一个进程序列。当需要时,程序会去进程池中获取一个进程。  

  如果进程池序列中没有可供使用的进程,那么程序就会等待,直到进程池中有可用进程为止

  理解:一个学校有很多教室,不同的班级轮流使用这些教室

  内置的一些方法:   

    apply 从进程池里取一个进程并同步执行

    apply_async 从进程池里取出一个进程并异步执行

    terminate 立刻关闭进程池

    join 主进程等待所有子进程执行完毕,必须在close或terminete之后

    close 等待所有进程结束才关闭线程池

  2.进程池的作用

  用来重复利用进程,节省资源

  3.同步执行:放个代码感受一下,创建3个进程,循环执行5次任务,这时三个进程轮流执行这5个任务,问题来了,这三个进程号是不变的,也就是创建几个进程池里数字为几,最多就可以创建几个进程,不可不填。感受代码。

  同步的特点:一个一个执行我们的任务

技术分享图片
 1 from multiprocessing import Pool
 2 import time
 3 import os
 4 
 5 
 6 def func():
 7     time.sleep(1)
 8     print("run",os.getpid())  # 获取当前进程号
 9 
10 
11 def main():
12     p1 = Pool(3)  # 设定开启3个进程池
13     for i in range(5):
14         p1.apply(func)  # 设定异步执行任务
15 
16 
17 if __name__ == __main__:
18     main()
View Code
打印结果:
run 7996
run 9560
run 4184
run 7996
run 9560

  4.异步执行:所有进程同时执行任务 ,apply_async必须和close()必须和join() 这三个必须一起使用,join()要放在for循环之外

  

技术分享图片
 1 from multiprocessing import Pool
 2 import time
 3 import os
 4 
 5 
 6 def func():
 7     time.sleep(1)
 8     print("run",os.getpid())
 9 
10 
11 def main():
12     p1 = Pool(3)  # 设定开启3个进程池
13     for i in range(5):
14         p1.apply_async(func)  # 异步,有问题,必须加入join跟close
15 
16     p1.close()  # 关闭进程池,不在接收新的任务
17     p1.join()  # 让我们的主进程等待进程池完成再结束
18 
19 
20 if __name__ == __main__:
21     main()
View Code
打印结果: 前三行同时出现,停顿1S,后面两行同时出现
run 10512
run 12788
run 1688
run 10512
run 12788

  案例:复制文件夹

  链接:http://blog.csdn.net/chaipp0607/article/details/60779129

 

  并发:看上去像同时发生的,指应用能够交替执行不同的任务,注意点,能够处理多个任务,没说非要同时。
  并行:指应用能够同时执行不同的任务,注意点,必须同时。

  两者区别:一个是交替执行,一个是同时执行。

  


以上是关于python进程学习的主要内容,如果未能解决你的问题,请参考以下文章

线程学习知识点总结

学习笔记:python3,代码片段(2017)

Python学习总结

python多线程

学习 PyQt5。在我的代码片段中找不到错误 [关闭]

[Python3] 043 多线程 简介