操作系统简介(转自林海峰老师博客介绍)


#一 操作系统的作用:
1:隐藏丑陋复杂的硬件接口,提供良好的抽象接口
2:管理、调度进程,并且将多个进程对硬件的竞争变得有序 #二 多道技术:
1.产生背景:针对单核,实现并发
ps:
现在的主机一般是多核,那么每个核都会利用多道技术
有4个cpu,运行于cpu1的某个程序遇到io阻塞,会等到io结束再重新调度,会被调度到4个
cpu中的任意一个,具体由操作系统调度算法决定。 2.空间上的复用:如内存中同时有多道程序
3.时间上的复用:复用一个cpu的时间片
强调:遇到io切,占用cpu时间过长也切,核心在于切之前将进程的状态保存下来,这样
才能保证下次切换回来时,能基于上次切走的位置继续运行

进程与程序的区别:

程序仅仅是一堆代码而已,而进程指的是程序的运行过程。

需要强调的是,同一个程序执行两次,那也是两个进程。

进程的创建都是操作系统完成的。


开启进程的两种方式:

第一种方法:

 from multiprocessing import Process    #引用这个函数
import time
def work(name):
print('task <%s> is runing' %name)
time.sleep(2)
print('task <%s> is done' % name) if __name__ == '__main__':
# Process(target=work,kwargs={'name':'egon'}) #target后边跟的是你的函数名,传值的方式有两种:一种是args(单个参数),一种是kwargs(多个参数)
p1=Process(target=work,args=('egon',))
p2=Process(target=work,args=('alex',))
p1.start()
p2.start()
print('主')
15  #主
  #task <egon> is runing
  #task <alex> is runing
  #task <egon> is done
  #task <alex> is done

打印的结果如15所示:
为什么会先打印"主"这个字段????

是因为主程序在执行的过程中,会告诉操作系统开一个进程,但是开完进程以后,操作系统不会在这等着(相当于只是发了一个开启进程的信号),然后会继续向后边执行。

等到所有的子进程执行完后,主进程才会执行完成。(如果在执行过程中,主进程挂掉,子进程就会成为僵尸进程)

开启进程的方式二:

from multiprocessing import Process
import time
class MyProcess(Process): #自己定义了一个类继承一下进程的类
def __init__(self,name):
super().__init__()   #先重用父类的功能,然后再去定义自己的,要不然会出错。
self.name=name def run(self):
print('task <%s> is runing' % self.name)
time.sleep(2)
print('task <%s> is done' % self.name) if __name__ == '__main__':
p=MyProcess('egon')
p.start() print('主')

UDP并发的套接字通信:

 from multiprocessing import Process
from socket import *
s=socket(AF_INET,SOCK_STREAM)
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(('127.0.0.1',8080))
s.listen(5)
def talK(conn,addr):
while True: #通信循环
try:
data=conn.recv(1024)
if not data:break
conn.send(data.upper())
except Exception:
break
conn.close() if __name__ == '__main__':
while True:
conn,addr=s.accept() #链接循环
p=Process(target=talK,args=(conn,addr))
p.start() s.close()

#将获取地址,和链接循环放在程序主体,通信循环定义成一个模块,这样可以实现并发。

#客户端
from socket import *
c=socket(AF_INET,SOCK_STREAM)
c.connect(('127.0.0.1',8080)) while True: #通信循环
msg=input('>>: ').strip()
if not msg:continue
c.send(msg.encode('utf-8'))
data=c.recv(1024)
print(data.decode('utf-8')) c.close()

客户端只是个程序,当他启动了就是一个进程。
启动多个,就是多个进程。


join方法(主进程等待子进程结果):

主程序的运行过程中需要子进程的执行结果,但正常的是不等的,这时候我们需要用到join方法。

from multiprocessing import Process
import time
def work(name):
print('task <%s> is runing' %name)
time.sleep(3)
print('task <%s> is done' % name) if __name__ == '__main__':
p1=Process(target=work,args=('egon',))
p2=Process(target=work,args=('alex',))
p3=Process(target=work,args=('yuanhao',)) # p1.start()
# p2.start()
# p3.start()
#
# p1.join() #主进程等,等待p1运行结束
# p2.join() #主进程等,等待p2运行结束
# p3.join() #主进程等,等待p3运行结束 p_l = [p1, p2, p3]
for p in p_l:
p.start() for p in p_l:
p.join() print('主')

这里边所有的进程都加入了join方法,但是其实是主进程把所有的进程都打开了,所有的子进程都在并发,其实主进程等待的是运行时间最长的子进程,运行时间最长的子进程结束,主进程等待结束。

#注意的一点:不能将这个开进程和join方法放到一个循环里边,这样的话,相当于是串行运行程序。等待时间是所有时间的总和。

错误的用法:

 p_l = [p1, p2, p3]
for p in p_l:
p.start()
# p.join()
# p1.start()
# p1.join()
# p2.start()
# p2.join()
# p3.start()
# p3.join()

Process对象的其他方法或属性:

p=Process(target=work,args=("egon",),name="")
p1.start() #p1.terminnate() zijinchengzaikai zijincheng
#热别注意,容易产生僵尸进程 #p1.is_alive() 判断这个进程是否是活着的 #p1.name() 打印p1的进程名 #p1.pid() #print("zhu",os.getpid()) #打印进程pid
#print("zhu",os.getppid()) #打印父进程pid

守护进程:

主进程创建守护进程,

其一:守护进程会在主进程代码执行结束后就终止

其二:守护进程无法在开启子进程,否则抛出异常。

注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止。

主进程结束后,子进程也完蛋了。

应用场景:监控(比如说子进程监控主进程的状态,主进程一旦挂掉,子进程也要随之挂掉)

from multiprocessing import Process
import time
def work(name):
print('task <%s> is runing' %name)
time.sleep(2)
print('task <%s> is done' % name) if __name__ == '__main__':
p1=Process(target=work,args=('egon',))
p1.daemon = True
p1.start() print('主')

小例子:

 #主进程代码运行完毕,守护进程就会结束
from multiprocessing import Process
import time
def foo():
print(123)
time.sleep(1)
print("end123") def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == '__main__': p1=Process(target=foo)
p2=Process(target=bar) p1.daemon=True
p1.start()
p2.start()
print("main-------") #打印该行则主进程代码结束,则守护进程p1应该被终止,可能会有p1任务执行的打印信息123,因为主进程打印main----时,p1也执行了,但是随即被终止

Day9 进程理论 开启进程的两种方式 多进程实现并发套接字 join方法 Process对象的其他属性或者方法 守护进程 操作系统介绍的更多相关文章

  1. 并发编程 - 进程 - 1.开启子进程的两种方式/2.查看pid/3.Process对象的其他属性或方法/4.守护进程

    1.开启子进程的两种方式: # 方式1: from multiprocessing import Process import time def task(name): print('%s is ru ...

  2. python 之 并发编程(线程理论,开启线程的两种方式,进程与线程的区别,线程对象的其他方法)

    9.9 线程理论 1.什么是线程 线程指的是一条流水线的工作过程 进程根本就不是一个执行单位,进程其实是一个资源单位,一个进程内自带一个线程,线程才是执行单位 2.进程VS线程 同一进程内的线程们共享 ...

  3. 并发编程 - 线程 - 1.开启线程的两种方式/2.进程与线程的区别/3.Thread对象的其他属性或方法/4.守护线程

    1.开启线程的两种方式: 进程,线程: 进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合)而线程才是cpu上的执行单位) 1.同一个进程内的多个线程共享该进程内的地址资源 2.创建线 ...

  4. python 之 并发编程(开启子进程的两种方式,进程对象的属性)

    第九章并发编程 同一个程序执行多次是多个进程 import time import os ​ print('爹是:',os.getppid()) #父进程PID,(pycharm) print('me ...

  5. Python 35 线程(1)线程理论、开启线程的两种方式

    一:线程理论 1 什么是线程 进程其实一个资源单位,而进程内的线程才是cpu上的执行单位 线程其实指的就是代码的执行过程2 为何要用线程   线程vs进程     1. 同一进程下的多个线程共享该进程 ...

  6. python 并发编程 多线程 开启线程的两种方式

    一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 二 开启线程的两种方式 第一种 每造一个进程,默认有一个线程,就是 ...

  7. DJango中开启事务的两种方式

    目录 Django中开启事务的两种方式 第一种 第二种 Django中开启事务的两种方式 第一种 from django.db import transaction with transaction. ...

  8. Process 开启子进程 的两种方式、join控制子进程、守护进程

    一.join控制子进程的一种方式 当主进程需要在子进程结束之后结束时,我们需要用到join来控制子进程. import time import random from multiprocessing ...

  9. 【java并发】传统线程技术中创建线程的两种方式

    传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...

随机推荐

  1. Linux_Oracle命令大全

     一,启动 1.#su - oracle              切换到oracle用户且切换到它的环境 2.$lsnrctl status           查看监听及数据库状态 3.$ls ...

  2. (八十八)VFL语言初步 - 实现布局

    [基本语法] VFL的语法为H:和V:开头,代表水平和垂直. 接下来如果要涉及距离,使用|-x-,x为距离的点数. 对于视图,用[ ]包围,例如[blueView]. ①下面的语句实现了blueVie ...

  3. iOS中 自定义cell升级版 (高级)

    接上次分享的自定义cell进行了优化:http://blog.csdn.net/qq_31810357/article/details/49611255 指定根视图: self.window.root ...

  4. UNIX环境高级编程——标准I/O库缓冲区和内核缓冲区的区别

    1.C标准库的I/O缓冲区         UNIX的传统 是Everything is a file,键盘.显示器.串口.磁盘等设备在/dev 目录下都有一个特殊的设备文件与之对应,这些设备文件也可 ...

  5. oracle ebs应用产品安全性-安全性规则

    定义: 通过为段指定包括下限值与上限值的值范围,可以定义安全性规则要素.安全性规则要素适用于包括在指定值范围内的所有段值. 可以将每个安全性规则要素标识为"包括"或"排除 ...

  6. Git添加文件改动时出错

    原来的主文件夹中替换了3个子文件夹,每个子文件夹有若干同名文件,总共替换了大概200多个文件吧. 然后在git主文件夹中使用git add .指令出现如下错误: apple@kissAir: iOS$ ...

  7. Android官方技术文档翻译——迁移 Gradle 项目到1.0.0 版本

    本文译自Android官方技术文档<Migrating Gradle Projects to version 1.0.0>,原文地址:http://tools.android.com/te ...

  8. 【matlab编程】matlab随机数函数

    Matlab内部函数 a. 基本随机数 Matlab中有两个最基本生成随机数的函数. 1.rand() 生成(0,1)区间上均匀分布的随机变量.基本语法: rand([M,N,P ...]) 生成排列 ...

  9. ffdshow 源代码分析 6: 对解码器的dll的封装(libavcodec)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  10. 线性表链式存储设计与实现 - API实现

    基本概念 链式存储定义 为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息. 表头结点 链表中的第一个结点,包含指向第一个数据元素的指针以 ...