2018.11.07python学习第三十五天

一:什么是进程?

进程指的是一个正在进行/运行的程序,进程是来用描述程序执行过程的虚拟概念。

二:操作系统理论:

1.什么是操作系统?

​ 操作系统是一个协调/管理/控制计算机硬件资源与应用软件资源的一段控制程序。

2.操作系统两大功能:

​ 1.将复杂的硬件操作封装成简单的接口,给应用程序或者用户去使用。

​ 2.将多个进程对硬件的竞争变得有序。

3.操作系统发展史

​ 第一代计算机:程序是固定的,无法修改,某种计算机只能敢某种特定的工作

​ 第二代计算机:批处理系统,需要人工参与,将程序集中到一起,给计算机统一执行。

​ 第三代计算机:为了更好的利用计算机资源,产生了多道技术。

​ 并发:在统一个时间段内,发生多个事情,多个任务看起来像是同时运行的

​ 串行:一个任务完完整整的运行完毕,才能运行下一个任务

​ 多道技术:

​ 1.空间复用:多个任务复用内存空间,将内存分为多个区域,每个区域存储不同的程序

​ 2.时间复用:多个任务复用CPU的时间

​ 1.一个任务占用CPU时间过长会被操作系统强行剥夺走CPU的权限:比起串行执

​ 行反而会降低效率
​ 2.一个任务遇到i/o操作也会被操作系统强行剥夺走cpu的权限,但是切换前需要

​ 保存当前的运行状态,以便恢复执行,提高效率。比起串行执行可以提升效率

三:同步/异步&阻塞/非阻塞

同步
# 所谓同步就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回。如果按照这个定
# 义,那么绝大多数函数都是同步调用。但是一般而言,我们在说同步,异步的时候,特指那血需要# 其他部件协作或者需要一定时间完成的任务。

# 发起同步调用后,就在原地等着任务结束,根本不考虑任务时在计算还是在I/O阻塞,就是简单的
# 等待任务结束。
异步
# 异步的概念和同步是相对的。当一个异步功能调用发出后,调用者不能立刻得到结果。当异步功能# 完成后,通过状态/通知或者调用来通知调用者,如果异步功能用状态来通知,那么调用者就需要
# 每隔一定时间检查一次,效率就很低。如果是使用通知的方式,效率则高很多,因为异步功能几乎# 不需要做额外的操作。至于回调函数,其实和通知没什么区别。
阻塞
# 阻塞调用时指调用结果返回之前,当前线程回被挂起(如i/o操作)。函数只有在得到结果之后才
# 会将阻塞的线程激活。有人也会把阻塞调用和和同步调用等同起来,实际上它是不同的。对于同步
# 调用者来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。
非阻塞
# 非阻塞和阻塞的概念是像对应,指在不能立刻得到结果之前也回立刻返回,同时该函数不会阻塞当  # 前线程
小结:

​ 1.同步与异步针对的是函数/任务的调用方式:同步就是当一个进程发起了一个函数(任务)调

​ 用的时候,一直等到函数(任务)完成,而进程继续处于激活状态。而异步情况是当一个发

​ 起一个函数(任务)调用的时候,不会等函数返回,而是继续往下执行,当函数返回的时候

​ 通过状态/通知/事件等方式通知进程任务完成。

​ 2.阻塞和非阻塞针对的是进程或线程:阻塞是当请求不能满足的时候就将进程挂起,而非阻塞

​ 则不会则是当前进程

注意:串行中阻塞和等待的区别,阻塞是指在进行I/O操作时,cpu被分配给其他进程而等待是cpu
​ 还在该程序中,执行权没有发生改变。

四:进程

1.进程和程序的区别

​ 程序:一堆代码

​ 进程:程序执行的过程

​ 进程的概念起源于操作系统,进程是操作系统最核心的概念,操作系统其他所有的概念都是围

​ 绕进程来的。

注意:同一个程序执行两次,那也是两个进程,比如打开QQ,登录两个不同的QQ号。
2.启动进程的方式
1.系统初始化,回产生一个根进程

​ 2.用户的交互请求,鼠标双击某个程序

​ 3.在一个进程中,发起了系统调用启动了另个进程

​ 4.批处理作业开始,某些专用计算机可能还是使用(了解一下就可以了)

方式一
# 导入模块Process
from multiprocess import Process
import time

# 需要子进程执行的任务
def task(name):
	print('%s is running' %name)
	time.sleep(3)
	print('%s is stop' %name)
	
if __name__ == '__main__': # if 下面所有的内容都是父进程
	# 告诉系统创建一个进程对象
	p = Process( target = task,args = ('aaa',))
	# 开始执行子进程
	p.start()
	print('hello')
	print('see you')
方式二
# 导入模块Process
from multiprocessing import Process

# 定义一个类,继承Process
class Myprocess(Process):
	# 当子进程被执行的时候就执行run函数
	def run(self):
		# 需要子进程做的事情
		print('need to do sth for run')

if __name__ == '__main__':
	Myprocess().start()
	print('hello')
3.父进程和子进程的执行顺序
from multiprocessing import Process
import time


def task(name):
    print('%s is running' %name)
    time.sleep(3)
    print('%s is stop' %name)
    
    

if __name__ == '__main__':
    p = Process(target = task,args = ('aaa',))
	p.start()
	print('hello')
	time.sleep(4)
	print('see u')
    
# 打印结果
# hello
# aaa is running
# aaa is stop
# see u 

# 所以,子进程和父进程的执行顺序就是,从上往下正常执行父进程,如果父进程的某一行code开# 始p.start()调用了子进程,那么子进程的内容和父进程下面的代码会并发执行。
4.子进程对象p.join()的用法
from multiprocessing import Process
import time

def task(name):
	print('%s is running' %name)
    time.sleep(3)
    print('%s is stop' %name)

if __name__ == '__main__':
    p = Process(target = task,args = ('aaa',))
	p.start()
	print('hello')
	p.join()	
	print('see u')
    
# join() 的用法就是父进程要等待子进程的时间,如果超过该时间,不管子进程中的代码有没
# 有执行完成,父进程都执行下面的代码。 如果不传入参数,则是一定要等待子进程执行完成后才# 执行后面的代码
5.进程对象常用的属性
from multiprocessing import Process
import time

def task(name):
	print('%s is running' %name)
    time.sleep(3)
    print('%s is stop' %name)

if __name__ == '__main__':
    p = Process(target = task,args = ('aaa',))
	p.start()
	print('hello')
	p.join()	## 1.join	等待时间
	p.terminate()	## 2.terminate()	结束子进程
	print(p.is_alive())		## 3.is_alive()		判断进程是否还存活
	print('see u')
	
	import os
	print(os.getpid())	## 4.getpid()	获取当前进程的id
	print(os.getppid())	## 5.getppid() 	获取父进程的id

# 总结:进程主要相关属性
# 1.join()
# 2.terminate()
# 3.is_alive()
# 4.getpid()/getppid()
6.僵尸进程和孤儿进程
#僵尸进程:
	#一个进程任务一旦执行完成了就死亡了,但是操作系统不会立即清理,这样可以让父进程访问到子进程的信息。我们把这样的任务完成的,但是没有被操作系统清理的进程成为僵尸进程,越少越好,因为会占用内存空间。
	
#孤儿进程:
	#顾名思义,就是一个父进程已经死亡了,但是它的子孙进程还在执行这,这个时候,操作系统会扮演孤儿院的角色,接管这些孤儿进程。
注意:
父进程中,创建一个子进程对象p,然后再调用p.start()的过程中,父进程扮演的角色就是,通知操作系统我要创建一个子进程,但是操作系统什么时候创建完成,什么时候执行子进程,我们无法预知。

posted on 2018-11-07 21:25  撩与诗人  阅读(77)  评论(0编辑  收藏  举报