Python之路PythonThread,第一篇,进程1

python3 进程1

多任务编程: 可以有效的利用计算机资源,同时执行多个任务,

进程:进程就是程序在计算机中一次执行的结果;

进程和程序的区别:

程序是一个静态文件的描述,不占用计算机的系统资源;

进程是一个动态的过程,占有cpu内存等资源,有一定的生命周期;

* 同一个程序的不同执行过程即为不同的进程;

问题1 ,什么决定了进程的创建;

用户通过应用层程序进行进程的创建申请 ----》》

调用操作系统接口进行程序创建--》》

告知系统内核创建新的进程提供给应用层使用

问题2,进程如何占用CPU

       1,同一个内核同一时刻只能运行一个进程

        2, 多个进程对内核资源进行抢占,由操作系统内核进行分配

        3,哪个进程占有计算机内核我们称之为该进程占有CPU的时间片;

问题3, 进程在运行过程中的形态和附带内容;

PCB(进程控制块):在linux和unix操作系统中,进程创建后会在内存中开辟一块空间存放进程的相关信息,这个空间称之为PCB;

PID : 在操作系统中进程的唯一标识,是一个大于0的正整数,由系统自动分配

ps -aux 查看进程信息

 虚拟内存:每个进程占用4G内存地址空间,这里的内存指虚拟空间;

进程状态:

三态: 就绪态、  运行态 、   等待态

就绪态: 进程具备运行条件,等待系统分派处理器以便运行;

运行态:进程占有cpu处于运行状态

等待态: 又称为阻塞态或睡眠态, 指进程不具备运行条件,正在等待某些条件的达成

五态:  就绪态、  运行态 、   等待态 、  新建态、 终止态

新建态:创建一个进程的过程,直接表现为执行某个程序或在程序中创建新的进程;

终止态:进程执行结束,完成回收的过程;

D   等待态(不可中断)

S    等待态(可中断)

T    等待态(暂停状态)

R  运行态

Z  僵尸态

+   前台进行

N   低优先级的进程

<   高优先级的进程

l     有进程连接

s     会话组

进程的优先级:

优先级往往决定了一个进程的执行权限和占有系统资源的优先程度;

top : 动态查看系统进程运行的情况;

<   > 进行翻页查找

linux 系统优先级范围 (-20 ~ 19),其中(-20)优先级最高;

用户创建进程默认优先级为0

nice  : 以指定的优先级运行某个进程;

例: nice  -9  ./xxx.py  #以9为优先级运行程序

        sudo  nice  - - 9  ./xxx #以-9为优先级运行程序

renice  n  PID   : 修改一个正在运行的进程的优先级;

例: renice  8  6277 将6277号进程优先级修改为8

父子进程:在系统中除了初始化进程之外每个进程都是由父进程创建的,每个进程有一个唯一的父进程,可能有多个子进程;

pstree

总结:

1,什么是进程

2,进程和程序的区别

3,进程的几种状态及相互间的转换

4,什么是PCB   PID   CPU时间片

需求:两件不相关事情希望同时来做

方案1: 写两个进程,分别承担不同的事情,各自执行;

          分析:1,两个程序比较麻烦; 2,无法确定两个程序应该在什么时间开始运行;

方案2: 写一个程序,在程序中指定位置调用接口来创建新的进程;

实现方法:

通过 os.fork() 函数实现

fork()

功能:创建一个新的进程

参数:无

返回值: < 0   #表示进程创建失败;

                ==0  #在子进程中fork的返回值为0;

                 > 0   #在父进程中fork的返回值大于0;

(fork是os模块函数,只能在linux和unix下使用)

测试1: 在父进程中fork之前的内容,子进程同样也会复制; 但是父子进程空间内容的修改不会互相影响;

测试2:父子进程在执行上互不影响,理论上不一定谁先执行;

测试3: 子进程虽然复制父进程的空间,但是也有自己的独特的特性,比如自己的PID,进程控制块,进程栈等。父进程中fork的返回值即为创建的子进程的PID号;

进程相关函数:

os.getpid()

功能: 获取当前进程的PID号;

os.getppid()

功能:获取当前进程父进程的PID号;

 1 #os 模块提供大量和系统相关的功能函数接口
 2 #os模块的使用是系统相关的 在不同的系统中
 3 #可能使用方法不同 
 4 import os 
 5 
 6 print('before create process')
 7 a = 10
 8 
 9 #创建新的进程
10 pid = os.fork()
11 
12 if pid < 0:
13     print('create process failed')
14 elif pid == 0:
15     print('This is the new process')
16     print(a)
17     a = 1000
18 else:
19     print('This is the parent process')
20 
21 print("The process end")
22 print(a)
23 
24 ##############fork1#
25 import os 
26 import time 
27 
28 #创建新的进程
29 pid = os.fork()
30 
31 if pid < 0:
32     print('create process failed')
33 elif pid == 0:
34     print('pid:',pid)
35     while True:
36         time.sleep(0.8)
37         print('This is the new process')
38         #子进程的退出不会影响父进程
39         os._exit(0)
40 else:
41     #父进程中pid为子进程的PID号
42     print('parent pid:',pid)
43     while True:
44         time.sleep(1)
45         print('This is the parent process')
46 
47 print("The process end")
48 ############fork2#
49 import time 
50 
51 def fun1():
52     time.sleep(6)
53     print('做完第一件事情')
54 
55 def fun2():
56     time.sleep(4)
57     print('做完第二件事情') 
58 
59 # fun1()
60 # fun2()   
61 ###
62 import os 
63 import time
64 from test import * 
65 
66 #创建新的进程
67 pid = os.fork()
68 
69 if pid < 0:
70     print('create process failed')
71 elif pid == 0:
72     fun1()
73 else:
74     fun2()
75 #############fork3##
76 
77 import os 
78 
79 pid = os.fork()
80 
81 if pid < 0:
82     print('create process failed')
83 elif pid == 0:
84     print("Child process:")
85     print("当前进程的PID:",os.getpid())
86     print("当前进程父进程的PID:",os.getppid())
87 else:
88     print("Parent process:")
89     print("pid:",pid)
90     print("当前进程的PID号:",os.getpid())
View Code

结束一个进程

os._exit(status)

功能:结束一个进程

参数:一个数字表示进程的退出状态,通常0表示正常退出进程其他数字表示非正常退出

sys.exit([status])

功能:结束一个进程,如果处理了抛出的异常则不结束进程

参数:一个数字表示进程的退出状态,通常0表示正常退出进程其他数字表示非正常退出;

          还可以是一个字符串, 则在进程退出时会打印这个字符串;

 1 #####
 2 #!/usr/bin/python3
 3 
 4 import os
 5 import sys
 6 
 7 os._exit(0) #结束进程,不执行后面的语句;
 8 
 9 print('process over')
10 ~
11 ######
12 #!/usr/bin/python3
13 
14 import os
15 import sys
16 
17 #os._exit(0)
18 sys.exit() #结束进程,不执行后面的语句;
19 
20 
21 print('process over')
22 ########
23 
24 #!/usr/bin/python3
25 
26 import os
27 import sys
28 
29 #os._exit(0)
30 #sys.exit()
31 try:
32     sys.exit('结束了。')  #当它进行处理了异常,则执行下面的语句
33 except SystemExit as e:
34     print('++++'e)
35 
36 
37 print('process over')
38 
39 ###结果:
40 $ ./exit.py 
41 ++++ 结束了。
42 process over
43 
44 
45                          
View Code
 1 import os 
 2 import time 
 3 
 4 #创建新的进程
 5 pid = os.fork()
 6 
 7 if pid < 0:
 8     print('create process failed')
 9 elif pid == 0:
10     print('pid:',pid)
11     while True:
12         time.sleep(0.8)
13         print('This is the new process')
14         #子进程的退出不会影响父进程
15         os._exit(0)
16 else:
17     #父进程中pid为子进程的PID号
18     print('parent pid:',pid)
19     while True:
20         time.sleep(1)
21         print('This is the parent process')
22 
23 print("The process end")
View Code

僵尸进程:子进程先于父进程退出,父进程没有对子进程的退出做相应的处理,此时子进程就会变为僵尸进程;

影响:进程退出后,仍有部分信息残留在内存中占用空间,大量的僵尸进程会影响系统运行。所以应该尽量避免僵尸进程的产生;

 1 cat zombie.py 
 2 #!/usr/bin/python3
 3 
 4 import os
 5 import time
 6 
 7 pid = os.fork()
 8 
 9 if pid < 0:
10     print('create new process failed.')
11 elif pid == 0:
12     print('子进程退出了')
13     os._exit(0)
14 else:
15     time.sleep(1)
16     print('Child PID:',pid)
17     while True:
18         pass
19 ##
20 python3 zombie.py
21 子进程退出了
22 Child PID: 3710
23 ##
24 tarena     3710  0.0  0.0      0     0 pts/2    Z+   21:18   0:00 [python3] <defunct>
25 tarena     3711  0.0  0.3  39104  3224 pts/6    R+   21:18   0:00 ps -aux
View Code

孤儿进程:父进程先于子进程退出,此时子进程就会变成孤儿进程;

影响:当一个进程变为孤儿进程,系统就会自动的使用一个进程称为孤儿进程的父进程。当孤儿进程退出时,该系统进程会自动回收孤儿,使他不会称为僵尸;所以孤儿进程对系统资源没有什么影响;

 1 #!/usr/bin/python3
 2 
 3 import os
 4 import time
 5 
 6 pid = os.fork()
 7 
 8 if pid < 0:
 9     print('create new process failed.')
10 elif pid == 0:
11     print('父进程的PID:',os.getppid())
12     time.sleep(3)
13     print('父进程的PID',os.getppid())
14     print('子进程退出了')
15     os._exit(0)
16 else:
17     #time.sleep(1)
18     print('Child PID:',pid)
19     #while True:
20     #    pass
21 ###
22 Child PID: 3778
23 父进程的PID: 3777
24 #:~/process$ 父进程的PID 2073
25 子进程退出了
View Code

处理僵尸进程的方法:

1,让父进程先退出;(缺点:不好控制)

2,父进程处理子进程的退出;(阻塞父进程的运行)

os.wait()

功能:等待子进程退出进行处理;

参数:无

返回值:返回一个包含两个元素的元组,第一个是退出的子进程的PID号,第二个是子进程的退出状态;

(wait是一个阻塞函数,即 进程处于等待态,等待某种条件的达成才会继续运行;)

 1 import os
 2 import sys
 3 from time import sleep
 4 
 5 pid = os.fork()
 6 
 7 if pid < 0:
 8     print('create process failed.')
 9 elif pid == 0:
10     print('Child process...')
11     sleep(2)
12     sys.exit(6) #子进程退出(6x256=1536)
13 else:
14     p,status = os.wait()##wait阻塞等待子进程的退出
15     print('pid:',p,'status:',status)
16     print('Parent process...')
17 ####
18 Child process...
19 pid: 3838 status: 1536
20 Parent process...
View Code

 os.waitpid(pid,option)

功能:处理子进程的退出使其不会变成僵尸进程;

参数:pid  -1  等待任意子进程退出;

      pid > 0 表示等待指定进程号的子进程退出;

     option    0   表示阻塞等待

          option     WNOHANG  表示非阻塞状态;

返回值 : 同wait

wait() ====> waitpid(-1,0)

 1 import os
 2 import sys
 3 from time import sleep
 4 
 5 pid = os.fork()
 6 
 7 if pid < 0:
 8     print('create process failed.')
 9 elif pid == 0:
10     print('Child process...')
11     sleep(2)
12     sys.exit(6) #子进程退出
13 else:
14     #waitpid非阻塞等待子进程的退出
15     p,status = os.waitpid(-1,os.WNOHANG)
16     print('p:',p,'status:',status)
17     print(os.WEXITSTATUS(status))
18     print('Parent process...')
19 ###
20 $ python3  waitpid.py 
21 p: 0 status: 0
22 0
23 Parent process...
24 Child process...
View Code

使用open拷贝一个文件,要求将文件拷贝为两份
第一份为前半部分,第二份为后半部分
分别用父子进程拷贝

总结:

1.函数的使用 fork getpid getppid _exit exit wait
waitpid

2. 理解什么是僵尸进程什么是孤儿进程即两者产生的过程

3. 知道僵尸进程的危害和两种处理方法

4. 理解进程的创建流程

 

猜你喜欢

转载自www.cnblogs.com/weizitianming/p/9164025.html
今日推荐