python-study-32

复习

上节课复习:
    1、操作系统(现代操作系统):
        操作系统是位于计算机硬件于软件之间的控制程序
        作用:
            1、将硬件的复杂操作封装成简单的接口,给用户或者应用程序使用
            2、将多个应用程序对硬件的竞争变的有序

    2、进程
        一个正在运行的程序,或者说是一个程序的运行过程

    3、串行、并发、并行
        串行:一个任务完完整运行完毕,才执行下一个
        并发:多个任务看起来是同时运行的,单核就可以实现并发
        并行:多个任务是真正意义上的同时运行,只有多核才能实现并行

    4、多道技术
        背景:想要再单核下实现并发(单核同一时刻只能执行一个任务)
        并发实现的本质就:切换+保存状态
        多道技术:
            1、空间上的复用=》多个任务共用一个内存条,但占用内存是彼此隔离的,而且是物理层面隔离的
            2、时间上的复用=》多个任务共用同一个cpu
                切换:
                    1、遇到io切换
                    2、一个任务占用cpu时间过长,或者有另外一个优先级更高的任务抢走cpu



今日内容:
    进程:
        1、进程理论
        2、开启进程的两种方式
        3、进程对象相关的属性或方法
    线程:
        4、线程理论
        5、开启线程的两种方式
        6、先从对象相关的属性或方法
View Code

进程:
1、进程理论
2、开启进程的两种方式
3、进程对象相关的属性或方法

今日作业:
不用socketserver 实现并发通信
用多进程实现并发通信

from socket import *
from multiprocessing import Process

server=socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5)

def talk(conn,client_addr):
    while True:
        try:
            msg=conn.recv(1024)
            if not msg:break
            conn.send(msg.upper())
            msg = msg.decode('utf-8')
            print(msg)

        except Exception:
            break
if __name__ == '__main__': #windows下start进程一定要写到这下面
    while True:
        conn,client_addr=server.accept()
        print(conn,client_addr)
        p=Process(target=talk,args=(conn,client_addr))
        p.start()
server
import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))

while True:
    msg=input('>>: ').strip()
    if len(msg) == 0:continue
    phone.send(msg.encode('utf-8'))

    data=phone.recv(1024)
    print(data.decode('utf-8'))

phone.close()
client

1、进程理论

进程是对正在运行程序的一个抽象
操作系统的其他所有内容都是围绕进程的概念展开的

操作系统的两大功能:
            1、将硬件的复杂操作封装成简单的接口,给用户或者应用程序使用
            2、将多个应用程序对硬件的竞争变的有序

应用程序请求---》操作系统----》cpu
真正干活的是cpu,cpu同一时刻只能执行一个任务
多道技术就是为了并发产生的:切换+保存状态

cpu+多道技术就可以实现并发
多道技术解决二代计算机的串行执行问题:
            1、空间上的复用=》多个任务共用一个内存条,但占用内存是彼此隔离的,而且是物理层面隔离的
            2、时间上的复用=》多个任务共用同一个cpu
                切换:
                    1、遇到io切换
                    2、一个任务占用cpu时间过长,或者有另外一个优先级更高的任务抢走cpu

操作系统控制执行多道技术:应用程序向操作系统发起请求,操作系统控制cpu执行程序,根据空间和时间的复用来分配cpu。实现并发

time.sleep(sleep) 模拟i/o --》 操作系统 --》 cpu切换执行别的程序
View Code

2、开启进程的两种方式

# # 方式一:process
from multiprocessing import Process
import time

def task(x):
    print('%s is running' %x)
    time.sleep(3)
    print('%s is done' %x)

if __name__ == '__main__':
    p=Process(target=task,args=('子进程',)) # 如果args=(),括号内只有一个参数,一定记住加逗号 调用类产生对象
    p.start() # 对象绑定方法 只是向操作系统发送一个开启子进程的信号  开子进程信号放在main后 防止win系统重复导入

    print('')

    
##方式二:自定义类继承process方式
from multiprocessing import Process
import time

class Myprocess(Process):
    def __init__(self,x):
        super().__init__()
        self.name=x

    def run(self):
        print('%s is running' %self.name)
        time.sleep(3)
        print('%s is done' %self.name)

if __name__ == '__main__':
    p=Myprocess('子进程1')
    p.start()  #p.run()
    print('')

    
子进程开启原理:向操作系统发送一个开启子进程的信号,父进程空间,数据复制一份到子进程空间
ps:
windows系统中  复制父数据的方法:子进程将父文件当做模块导入子进程空间 导入的成果放入子名称空间 会重复导入,所以加main 只在当做执行文件时才会执行下面的代码
linux系统中 没有这种问题但是为了兼容性,统一标准也这么做

父进程执行完毕但不会结束,要等子进程全都结束才会统一回收pid,等资源 然后才会结束 
僵尸进程是子进程运行完毕的一种状态,内存,硬盘等资源已经回收了 但是pid等 还没有回收 留给父进程查看 本身无害
父进程死掉之后,子进程会被系统的init最终父进程统一回收,时间可能会慢点 但是也无害 pid,内存等资源也会回收 称为孤儿进程

父进程不死的僵尸进程才是有害的,占用pid,内存 造成其他的程序起不来,因为资源已经占用完了
解决方法是:杀死父进程,让子进程自动进入init进程,统一管理,回收pid 内存 等资源

进程的内存空间是彼此隔离的,数据互不影响
View Code

3、进程对象相关的属性或方法

让父进程在原地等待,等到子进程运行完毕后,才执行下一行代码
p.start()
p.join() 

开启多个子进程
from multiprocessing import Process
import time

def task(name,n):
    print('%s is running ' %name)
    time.sleep(n)
    print('%s is done ' % name)

if __name__ == '__main__':
    p_l=[]
    start=time.time()
    for i in range(1,4):
        p=Process(target=task,args=('子进程%s' %i,i))
        p_l.append(p)
        p.start()

    for p in p_l:
        p.join()

    stop=time.time()
    print('',(stop-start))

    
父进程内查看子pid的方式
p.start()
print(p.pid)

子进程内查看自己的pid
os.getpid()

当前进程内查看父进程pid
os.getppid()

父进程中查看看子进程名:
p1.start()
print(p.name)

子进程中查看自己的进程名
from multiprocessing import Process,current_process
current_process().name

父进程中查看子进程是否存活
p1.start()
print(p.is_alive())  #True
p.join()
print(p.is_alive()) #False

父进程中发请求---os干掉子进程
p.terminate()
time.sleep(1)
print(p.is_alive())
View Code

 

原文地址:https://www.cnblogs.com/xujinjin18/p/9295250.html