1.オペレーティングシステムの基本
A.オペレーティングシステムの役割
1.非表示に醜い複雑なハードウェア・インタフェース、優れた抽象インターフェースを提供します
ハードウェアの競合2.管理、スケジューリング処理、および複数のプロセスが整然となり、
II。マルチチャネル技術
1.空間多重
複数のプログラムは、コンピュータハードウェアのセットを共有します
時間に多重2
+状態の切り替えを保存
1.プログラムは、I / O操作を検出すると、オペレーティングシステムは、CPUがプログラムの実行権限を奪うだろう(CPU使用率を向上させるために、それはプログラムの実行の効率には影響しません)
長い時間のためのプログラムがCPUを占有する場合2.、CPUのオペレーティングシステムは、(プログラムのパフォーマンスが低下)プログラムの実行権限を奪うだろう
プロセスにおける基本的な考え方
プロセスとは何ですか
プログラムプログラムは、それが資源配分とスケジューリングの基本単位であり、そのプロセスが実行されているコードの束である基礎となるオペレーティング・システム・アーキテクチャです。
プロセスのスケジューリングアルゴリズム
1. FCFSスケジューリングアルゴリズム
2.短い動作優先度スケジューリングアルゴリズム
3.ラウンドロビン方式
4.多段フィードバックキュー
第一及び第二のアルゴリズムは、短いジョブの最初の非友好的、非友好的な長いための第二のジョブなので、現代のコンピュータプロセスは第三及び第四のプロセスに基づいて実現される明らかな欠点を有しています図に示すように。
パラレルおよび同時プロセス
同時実行:実行のように見えます
パラレル:本当の意味で同じ時間を実行します
注:単核並列計算機を実現することはできないが、同時に実現することができ、プロセッサの並列複数実装する必要があります
プロセスの三つの状態
1.レディ状態:
プロセスがすでにすべての準備を行っている場合は、他のCPUで、この時点で状態がレディ状態で、行わ
2. Run状態
プロセスは、CPUが実行されているとき、状態がこの時点では、状態の実装であります
3.状態を遮断します:
プロセスは、私が実行されるいくつかの必要な過程で発生した場合、CPUは他のプロセスの実装、状態は、状態をブロックしている今回の賛成でプロセスを放棄しますと、/ O操作を続行できません
1 # 此时程序处于就绪态 2 import time # 运行这串代码时处于运行态 3 4 print('程序开始执行') 5 msg = input('>>>:') # 进入阻塞态 6 # 进入就绪态 7 print(msg) # 进入运行态 8 time.sleep(1) # 进入阻塞态 9 # 进入就绪态 10 print('程序结束运行') # 进入运行态 11 # 结束运行
同步异步
同步就是一个任务的完成必须等待另一个任务完成后才能算完成(类似于排队,程序的层面就是卡住了)
异步就是一个任务在执行的完成不需要知道另一个任务是否完成,只要自己的任务完成就算完成了(类似于叫号,另一个任务的完成结果是要的,但是是通过其他方式获取)
阻塞非阻塞
阻塞就是进程不在执行,处于阻塞态
非阻塞就是进程还在执行,处于就绪态或者运行态
两者组合成为四种状态
1.同步阻塞:只能做一件事情,并且处于阻塞态,效率最低
2.异步阻塞:因为等待某个事件而处于阻塞态,但是他不依赖于其他任务,所以事件处理完成就可以了
3.同步非阻塞:需要依赖于另一个任务的完成,就算自己的任务先完成了,但是还得等其他任务,效率也是地下的
4.异步非阻塞:不需要依赖于其他任务,自己又是非阻塞状态,可想而知效率是最高的
3.创建进程的两种方式
在python中创建进程需要导入一个multiprocess模块,他是python中操作、管理进程的一个包,他包含了和进程有关的所有子模块
multiprocess.process模块
process模块是一个创建进程的模块
创建进程就是在内存中重新开辟一块属于进程的独立的内存空间
进程和进程之间的数据是隔离的,无法直接交互,但是可以通过某些技术实现间接交互
1 from multiprocessing import Process 2 import time 3 4 age = 18 5 6 def run(msg): 7 global age 8 age = 28 9 print('%s开始'%msg) 10 print(age) # 子进程中的是28,两者无法访问 11 time.sleep(1) 12 print('%s结束'%msg) 13 14 ''' 15 windows会在进程创建时会以模块的方式从上到下的执行一遍, 16 所以在windows中创建进程一定要在if __name__ == '__main__':代码块中创建 17 linux中创建进程会直接复制一份 18 ''' 19 if __name__ == '__main__': 20 p = Process(target=run,args=('子进程',)) # 生成一个进程对象 21 p.start() # 创建一个进程 22 print(age) # 主进程中的age是18 23 print('主进程') # 主进程中的内容
1 from multiprocessing import Process 2 import time 3 age = 18 4 # 新建一个类继承父类Process 5 class MyProcess(Process): 6 def __init__(self,msg): 7 super().__init__() 8 self.msg = msg 9 10 def run(self): 11 global age 12 age = 28 13 print('%s开始'%self.msg) 14 print(age) 15 time.sleep(1) 16 print('%s结束'%self.msg) 17 18 if __name__ == '__main__': 19 p = MyProcess('子进程',) 20 p.start() 21 print(age) 22 print('主进程')
4.进程方法join
在上述创建进程代码中,父进程执行完毕之后才会执行子进程,其实两者并没有先后的关系,执行的顺序是操作系统来决定的,并且生成子进程也会消耗一段时间,故子进程在父进程之后,如果我们想要实现子进程完成之后在执行父进程,则需要join方法
1 from multiprocessing import Process 2 import time 3 4 def run(msg,i): 5 print('%s开始'%msg) 6 time.sleep(i) 7 print('%s结束'%msg) 8 9 if __name__ == '__main__': 10 start = time.time() # 记录开始时间 11 p = Process(target=run,args=('子进程',0)) 12 p1 = Process(target=run,args=('子进程1',1)) 13 p2 = Process(target=run,args=('子进程2',2)) 14 p3 = Process(target=run,args=('子进程3',3)) 15 p.start() 16 p1.start() 17 p2.start() 18 p3.start() 19 p.join() # 加入该方法后子进程会先执行完毕 20 p1.join() 21 p2.join() 22 p3.join() 23 end = time.time() # 记录结束时间 24 print('父进程') 25 print(end - start) # 打印总共的运行时间
join方法会等待所有子进程结束后再结束父进程,但是各个进程之间是互相独立的,他们等待的时间都在运行着,所以最后的运行时间是按照最长的等待时间加上真正的运行时间
5.进程间数据隔离问题
1 from multiprocessing import Process 2 age = 18 3 4 def run(): 5 global age 6 age = 28 7 print('子进程的age:%s'%age) 8 9 if __name__ == '__main__': 10 p = Process(target=run) 11 p.start() 12 p.join() 13 print('主进程的age:%s' % age)
子进程更改了age,主进程中的age并没有跟着改变
6.进程对象及其他方法
os.getpid:可以查看当前进程的pid(进程id)
os.getppid:可以查看当前进程的父进程的pid(进程id)
current_process模块:可以查看当前进程的pid(进程id),和os.getpid一样
p.terminate:强制终止子进程p
p.is_alive():判断子进程p是否还存活
1 from multiprocessing import Process,current_process 2 import time 3 import os 4 5 def run(): 6 print('os模块的子进程的pid:%s'%os.getpid()) 7 print('current_process模块子进程的pid:%s'%current_process()) 8 time.sleep(1) 9 print('父进程的pid:%s'%os.getppid()) 10 11 if __name__ == '__main__': 12 p = Process(target=run) 13 p.start() 14 time.sleep(0.5) 15 p.terminate() # 杀死一个子进程,一旦执行到这句话,不管子进程中的代码执行到哪了,都会立刻结束子进程 16 print(p.is_alive()) # 判断子进程是否存活,是个bool类型的值 17 print('主进程的pid:%s' % os.getpid()) 18 print('主进程的父进程的pid:%s' % os.getppid())
7.僵尸进程和孤儿进程
僵尸进程就是子进程死亡后,父进程还存放着子进程的pid之类的信息,一旦僵尸进程过多,会占用系统资源
父进程回收死亡的子进程(僵尸进程)资源的两种方式
1.join方法
2.父进程正常死亡
注意:所有进程都会步入僵尸进程
孤儿进程就是子进程没死,父进程意外死亡
针对linux会有儿童福利院(init),如果父进程意外死亡他所创建的子进程都会被福利院收养
8.守护进程
守护进程会随着主进程的结束而结束
主进程创建守护进程
守护进程会在主进程代码执行结束后就终止
守护进程内无法再开启子进程,否则就会抛出异常
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止
1 from multiprocessing import Process 2 import time 3 4 def run(msg): 5 print('%s开始'%msg) 6 time.sleep(1) 7 print('%s结束'%msg) 8 9 if __name__ == '__main__': 10 p = Process(target=run,args=('子进程',)) 11 p.daemon = True # 默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置 12 p.start() 13 time.sleep(1) 14 print('主进程结束')
8.互斥锁
一个简易的没有互斥锁的抢票软件
1 import json 2 from multiprocessing import Process 3 import time 4 5 # 查票 6 def search(i): 7 with open('ticket','r',encoding='utf-8') as f: 8 json_dict = f.read() 9 dict = json.loads(json_dict) 10 print('用户%s余票还有%s'%(i,dict.get('ticket'))) 11 12 # 买票 13 def buy(i): 14 with open('ticket','r',encoding='utf-8') as f: 15 json_dict = f.read() 16 dict = json.loads(json_dict) 17 time.sleep(1) 18 if dict.get('ticket') > 0 : 19 dict['ticket'] -= 1 20 with open('ticket','w', encoding='utf-8')as f: 21 d = json.dumps(dict) 22 f.write(d) 23 print('用户%s抢票成功'%i) 24 else: 25 print('用户%s卖完了'%i) 26 def run(i): 27 search(i) 28 buy(i) 29 30 if __name__ == '__main__': 31 for i in range(1,10): 32 p = Process(target=run,args=(i,)) 33 p.start()
当余票为1的时候,每个人都抢到了,这显然是不被允许的
这时候就要加入互斥锁
互斥锁:
将并发变成串行,虽然降低了效率但是提高了数据的安全
注意:
1.不要轻易的使用锁,容易造成死锁现象
2.只在处理数据的部分加锁,不要在全局加锁
3.锁必须在主进程中产生,不要在全局加锁
一个简易的加入了互斥锁的抢票系统
1 import json 2 from multiprocessing import Process,Lock 3 import time 4 5 # 查票 6 def search(i): 7 with open('ticket','r',encoding='utf-8') as f: 8 json_dict = f.read() 9 dict = json.loads(json_dict) 10 print('用户%s余票还有%s'%(i,dict.get('ticket'))) 11 12 # 买票 13 def buy(i): 14 with open('ticket','r',encoding='utf-8') as f: 15 json_dict = f.read() 16 dict = json.loads(json_dict) 17 time.sleep(1) 18 if dict.get('ticket') > 0 : 19 dict['ticket'] -= 1 20 with open('ticket','w', encoding='utf-8')as f: 21 d = json.dumps(dict) 22 f.write(d) 23 print('用户%s抢票成功'%i) 24 else: 25 print('用户%s卖完了'%i) 26 27 def run(i,mutex): 28 search(i) 29 mutex.acquire() # 抢锁,有人抢到了这把锁,其他人都要等他用完才能再抢 30 buy(i) 31 mutex.release() # 释放锁 32 33 if __name__ == '__main__': 34 mutex = Lock() # 在主进程中生成一把锁 35 for i in range(1,5): 36 p = Process(target=run,args=(i,mutex)) 37 p.start()