进程和并发编程

一、 操作系统:

  一个协调,管理和控制计算机硬件资源的和软件资源的控制程序。操作系统为与计算机硬件和应用软件之间,本质也是一个软件。

  操作系统由操作系统的内核(运行与内核态,管理硬件资源)以及系统调用(运行与用户态,为程序员写的应用程序提供系统调用接口)两部分组成。

  操作系统功能:1、隐藏了丑陋的硬件调用接口,为程序员提供了调用硬件资源的更好,更简单,更清晰的模型(系统调用接口),例如文件(无需关心怎么控制磁盘转动读写数据等细节)

         2、现代的操作系统运行同时运行多道程序,应用程序将应用程序对硬件资源的竞态请求变得有序化(如打印文件,不会出现一会打印文件a,没打印完就去打印文件b)

操作系统发展史:

第一代: 真空管和穿孔卡片

没有操作系统,所有的程序设计都是直接操控硬件。

程序员需预约,然后拿着插件版到机房,将插件版接到计算机里,独享计算机资源

优点:程序员可以独享资源,可以即时的提哦啊哈斯自己的程序

缺点:浪费计算机资源(同一时刻只有一个程序在内存中,被cpu调用执行,程序是串行的)

第二代:晶体管和批处理系统

解决的第一代的问题:把一堆人的输入灿盛一大波输入,在把输出攒成一大波输出

设计,生产,操作,程序员和维护直接有了明确的分工,有了操作系统的概念,有了程序设计语 言:FORTRAN语言或汇编语言,写在智商,然后穿孔打成卡片

优点:批处理,节省了机时

扫描二维码关注公众号,回复: 4686951 查看本文章

缺点:人参与流程,将磁带搬来搬去。计算过程仍是串行,等待结果和重新调试的过程都需要等同批次的其他程序都运作完才可以。

第三代: 集成电路芯片和多道程序设计

解决第二代的问题:通过卡片将内容从卡片读入磁盘,当作业结束时,操作系统能将一个作业从磁带读出,装进空出来的内存区域运行,这种技术叫 同事的外部设备联机操作:SPOOLING

多道技术背景:cpu在执行一个任务的过程中,若需操作硬盘,则发送操作硬盘的的指令,指令一旦发出,硬盘上的机械手臂滑动读取数据到内存中,cpu需要等待,对cpu来说这段时间已经很长很长,为了充分利用cpu,我们可以让cpu在这段时间内切换去做其他任务。

多道技术:多道指多个程序,多道技术解决多个程序竞争或共享同一个资源(cpu) 的有序调度问题。解决方式为多路复用,多路复用分为时间上的复用和空间上的复用

空间上的复用: 将内存分为几部分,每个部分放入一个程序这一昂,同一时间内存中就有了多道程序

缺点:内存分隔需要在硬件层面实现,由操作系统控制(如果不分割,不安全,不稳定)

时间上的复用: 当一个程序正在等待 I/O时,另一个程序可以使用cpu,如果一个程序占用cpu时间过长也会切换

分时操作系统: 多个联机终端 + 多道技术


补充: 多道技术

1.产生背景: 针对单核,实现并发

现在的主机一般都是多核,每个核都利用多道技术。例如有4个cpu, 运行于cpu1的摸个程序遇到io阻塞,会等到io结束再重新调度,会被调到四个cpu中的任意一个

  1. 空间上的复用:如内存中同时有多道程序

  2. 时间上的复用: 复用一个cpu的时间片

    主要:遇到io切, 当程序占用cpu时间过长也切,切之前 将进程的状态保存下来,这样下次胡来才能保证找到位置

 

第四代:个人计算机


二、进程

1.什么是进程

程序: 只是一堆代码

进程:执行中的程序,是一种抽象的概念

同一个程序执行两次,也是两个进程

2.并发和并行

并发: 多个事件同时发生,一个cpu 多个程序同时运行(伪并行)

并行: 多个事件同时进行,多个cpu 才能实现

3.同步,异步,阻塞,非阻塞

同步:发出一个功能调用时,在没有得到结果之前,调用就不会反回

异步:当一个异步功能调用发出后,调用者不能立刻得到结果

阻塞:如遇到IO操作,当前线程会被挂起

非阻塞:不能立刻得到结果之前也会立刻反回

小结: 同步和异步 针对的是函数/任务的调用方式

阻塞和非阻塞针对的是进程或线程:阻塞是当请求不能满足的时候将进程挂起,二非阻塞则不会阻塞当前进程

4.进程的创建

unix: 子进程将父进程内存中的值copy到自己的内存空间,因为子进程要帮父进程干活

windows: 不仅将父进程内存中的值copy到自己的内存空间,还加载一遍,(这样会导致重复创建子进程,因此要放在if.name == 'main' 下面

PID : 进程的ID ----> 由操作系统分配

os.getpid() -----> 获取自己的进程id

os.getppid() -----> 获取父进程的id

方法一: 直接创建Process 对象, 指定target 参数(args, kwargs)

from multiprocessing import Process
import time
import os

def index(num):
   while True:
       print(os.getpid())   # 获取自己的进程id (index)  
       print(os.getppid())  # 获取父进程的id (当前py文件)
       time.sleep(0.5)
       print('index is running...')
       
if .__name__ == '__main__':
   # 程序从这里开始运行
   print(os.getpid())  # 当前py文件
   print(os.getppid()) # pycharm
   
   #用来表示进程,创建一个对象,name 默认
   p = Process(target = index,args=("2",))
   p.start()

方法二:继承Process 覆盖run方法

from multiprocessing import Process
class Myprocess(Process):
   def.__init__(self,url):
       self.url = url
       super().__init__()  # 其他的属性还是要父类的
       
   def run (self):
       print('这在下载。。。')
       
       
if __name__ == '__main__':
   p = Myprocess('www.baidu.com.xx.mp4')
   p.start()    # 子进程启动后自动执行run方法
     

子进程和父进程间的内存相互隔离,修改子进程值,父进程不变

from multiprocessing import Process
import time
a = 100
def index():
   global a
   print('子进程',a)  # 结果100
   a = 0
   print('子进程', a)  # 结果0
   print('index is running...')

if __name__ == '__main__':

   p = Process(target = index)
   p.start()
   time.sleep(2)
   print('父进程',a)  #结果100

join函数

# join 让父进程等子进程结束后再执行
from multiprocessing import Process
import time
def index(number):
   print('第%s 次创建...'%number)
   time.sleep(2)

if __name__ == '__main__':
   start = time.time()
   list1 = []
   for i in range(5):
       p = Process(target = index,args = (i,))
       p.start()    # 没创建完可以继续运行以下代码
       list1.append(p)
   for p in list1:  # 将每个对象取出
       p.join()   # 当所有的进程创建完了以后,在执行之后的代码
   print(time.time()-start)

孤儿进程: 父进程已经终止,但自己还在运行,无害的

自动过继给操作系统

僵尸进程: 子进程执行完成所有任务,已经终止但还残留一些信息(进程id,进程名)

父进程没终止,但不去处理这些残留信息,导致信息专用系统内存,有害, 解决办法: 关闭父进程, 僵尸就变成了孤儿,操作系统会负责回收数据

启动任务管理器 结束 或 taskkill|'进程信息' |f

 

一、 进程: 正在执行的程序,是个抽象的概念

猜你喜欢

转载自www.cnblogs.com/Afrafre/p/10192274.html
今日推荐