zoukankan      html  css  js  c++  java
  • 网络编程(进程)

    一 、什么是进程

    进程:正在进行的一个过程或者说一个任务。而负责执行任务则是cpu。

    二 、进程与程序的区别

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

    三 、并发与并行

    无论是并行还是并发,在用户看来都是'同时'运行的,不管是进程还是线程,都只是一个任务而已,真是干活的是cpu,cpu来做这些任务,而一个cpu同一时刻只能执行一个任务

    一 并发:是伪并行,即看起来是同时运行。单个cpu+多道技术就可以实现并发

    就是各个进程来回切换

    二 并行:同时运行,只有具备多个cpu才能实现并行

    比如有四核 就可以同时运行四个进程 也就是同时干四个活

    进程的状态

    tail -f access.log |grep '404'

    执行程序tail,开启一个子进程,执行程序grep,开启另外一个子进程,两个进程之间基于管道'|'通讯,将tail的结果作为grep的输入。

    进程grep在等待输入(即I/O)时的状态称为阻塞,此时grep命令都无法运行

    其实在两种情况下会导致一个进程在逻辑上不能运行,

    1. 进程挂起是自身原因,遇到I/O阻塞,便要让出CPU让其他进程去执行,这样保证CPU一直在工作

    2. 与进程无关,是操作系统层面,可能会因为一个进程占用时间过多,或者优先级等原因,而调用其他的进程去使用CPU。

    因而一个进程由三种状态

     

    创建子进程

    一 、multiprocessing模块介绍 

    Python提供了multiprocessing。 multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,>提供了Process、Queue、Pipe、Lock等组件。

    需要再次强调的一点是:与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。

    二 、Process类的介绍

    创建进程的类:

    Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,可用来开启一个子进程
    
    强调:
    1. 需要使用关键字的方式来指定参数
    2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号

    参数介绍:

    group参数未使用,值始终为None
    
    target表示调用对象,即子进程要执行的任务
    
    args表示调用对象的位置参数元组,args=(1,2,'egon',)
    
    kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
    
    name为子进程的名称
    

    方法介绍:

    p.start():启动进程,并调用该子进程中的p.run() 
    p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法  
    
    p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
    p.is_alive():如果p仍然运行,返回True
    
    p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间。

    属性介绍:

    p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
    
    p.name:进程的名称
    
    p.pid:进程的pid
     

    三、 Process类的使用

    注意:在windows中Process()必须放到# if __name__ == '__main__':下

    创建并开启子进程的方式一

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import time
    import os
    from  multiprocessing import Process
    
    #一、函数方式
    def task(name):
        print('%s is running'%name)
        time.sleep(3)
        print('%s is done'%name)
    
    # if __name__ == '__main__':
    #     p = Process(target=task,args=('子进程',))
    #     p.start()
    #     print('主进程')
    
    #二、类方式
    
    class MyProcess(Process):#继承父类
        def __init__(self,name):
            super().__init__()
            self.name = name
        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()
        print('主进程',os.getpid(),os.getppid()) #查看进程pid ,ppid 查看父进程ID
    
    
    #输出
    
    主进程 9772 7536
    子进程1 is running

    四、 练习题

    1、思考开启进程的方式一和方式二各开启了几个进程?

    两个一个主进程 一个子进程

    2、进程之间的内存空间是共享的还是隔离的?下述代码的执行结果是什么?

    隔离的

    from multiprocessing import Process
    
    n=100 #在windows系统中应该把全局变量定义在if __name__ == '__main__'之上就可以了
    
    def work():
        global n
        n=0
        print('子进程内: ',n)
    
    
    if __name__ == '__main__':
        p=Process(target=work)
        p.start()
        print('主进程内: ',n)


    #输出
    主进程 100
    子进程内 0

    3、基于多进程实现并发的套接字通信?

    #服务端
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import socket
    from  multiprocessing import  Process
    
    
    def task(conn):
        while True:
            try:
                res = conn.recv(1024)
                if not res:break
                conn.send(res.upper())
            except ConnectionResetError:
                break
        conn.close()
    def process(ip_port):
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        server_socket.bind(ip_port)
        server_socket.listen(5)
        while True:
            conn,add = server_socket.accept()
            p =Process(target=task,args=(conn,))
            p.start()
        server_socket.close()
    if __name__ == '__main__':
        ip_port =('127.0.0.1',8080)
        process(ip_port)
    
    
    
    
    #客户端
    
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import socket
    client =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(('127.0.0.1',8080))
    while True:
        # client.connect(('127.0.0.1',8080))
        inp = input('>>>').strip()
        if not inp:break
        client.send(inp.encode('utf-8'))
        res = client.recv(1024)
        print(res.decode('utf-8'))
    client.close()

    4、思考每来一个客户端,服务端就开启一个新的进程来服务它,这种实现方式有无问题?

    有问题,若果进程太多机器就 down掉了



  • 相关阅读:
    python中的编码问题
    CVPR2018 Tutorial 之 Visual Recognition and Beyond
    hdu 1376 Octal Fractions
    hdu 1329 Hanoi Tower Troubles Again!
    hdu 1309 Loansome Car Buyer
    hdu 1333 Smith Numbers
    hdu 1288 Hat's Tea
    hdu 1284 钱币兑换问题
    hdu 1275 两车追及或相遇问题
    hdu 1270 小希的数表
  • 原文地址:https://www.cnblogs.com/mjiu/p/9094591.html
Copyright © 2011-2022 走看看