zoukankan      html  css  js  c++  java
  • python3 09 大纲

    上次内容回顾

    ## 网络编程

    ```
    socket
    osi七层协议
    tcp udp 传输层的两个常用协议
    tcp:面向连接的,可靠的,消息格式是面向流的
    udp:面向无连接的,不可靠的,消息格式是面向包的

    ```

    #### tcp和udp协议的socket

    ```
    #服务端
    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1',8001))
    
    server.listen()
    
    conn,addr = server.accept()
    
    from_client_msg = conn.recv(1024)
    print(from_client_msg)
    conn.send(b'hello')
    
    conn.close()
    server.close()
    
    #客户端
    import socket
    client = socket.socket()
    
    client.connect(('127.0.0.1',8001))
    
    client.send(b'haha')
    from_server_msg = client.recv(1024)
    print(from_server_msg)
    client.close()
    
    
    #################################
    udp协议下的socket
    #服务端
    import socket
    server = socket.socket(type=socket.SOCK_DGRAM)  # data gram 数据包
    server.bind(('127.0.0.1',8001))
    msg,client_addr = server.recvfrom(1024)
    print(msg)
    server.sendto(b'hello',client_addr)
    
    #客户端
    import socket
    client = socket.socket(type=socket.SOCK_DGRAM)  # data gram 数据包
    client.sendto(b'hehe',('127.0.0.1',8001))
    msg,server_addr = client.recvfrom(1024)
    print(msg)
    
    
    ```


    #### tcp的黏包

    ```python
    !.两个连续发送的小的数据包会被连在一起发送
    2.第一次发送的数据比较大,2000B,如果我另外一端接受数据时,不知道发送来的数据有多大,那么我可能写了一个recv1024,第二次再接受另外一端发送的第二个数据的时候,就会发现,第一次的剩余数据也会被接收到

    解决方法,发送数据前,先发送数据的长度
    struct 打包模块
    ret = struct.pack('i',len(信息)) --- 4个bytes数据,长度为4
    send(ret) ---- recv(4) ---- len_ret = struct.unpack('i',recv(4))[0] --recv(len_ret)

    ```

    #### 缓冲区:

    ```
    输入缓冲区 和 输出缓冲区
    ```

    subprocess模块

    ```
    conn = subprocess.Popen(
        cmd,
        shell=True,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE
    )
    conn.stdout.read().decode('gbk')  # standard out 标准输出
    conn.stderr.read().decode('gbk')  # standard error 标准错误输出
    ```


    #### socketserver

    ```


    import socketserver
    class MyServer(socketserver.BaseRequestHandler):  # 自定义类
        def handle(self):  # 方法名必须为handle
            while 1:
                from_client_msg = self.request.recv(1024)  # conn
                print(from_client_msg.decode('utf-8'))
                msg = input('to_client_msg>>>')
                self.request.send(msg.encode('utf-8'))
    
    if __name__ == '__main__':
        ip_port = ('127.0.0.1',8001)
        server = socketserver.ThreadingTCPServer(ip_port,MyServer)
        server.serve_forever()
    ```


    # 今日内容总结

    ## 进程 线程 协程


    ```

    并发:伪并行,遇到IO,帮我们提高代码执行效率
    并行:真正的同时运行,多核cpu

    ```



    #### 进程:

    ##### 父进程和子进程

    ```
    os.getpid()当前进程的id,getppid()父进程的id
    ```

    ##### 创建进程的两种方式:

    ```python
    方式1:


    from multiprocessing import Process
        def f(n)
            print(n)
        
        if __name__ == '__main__':
            p = Process(target=f,args=(1,))
            p.daemon = True
            p.start()
            p.join()  #主进程等待子进程
    方式2:

    from multiprocessing import Process
    
        class MyProcess(Process):
    
            def __init__(self,n):
                self.n = n
                super().__init__()
    
            #这是需要执行的代码逻辑
            def run(self):
                print(self.n)
                self.f2()
                print('xxxxxx')
            def f2(self):
                xxxx
    
        if __name__ == '__main__':
            p = MyProcess(20)
            p.start()
            print('主进程结束')
    ```


    进程三状态:

    ```
    就绪 运行 阻塞
    ```


    #### 进程间通信(IPC)

    ##### 队列

    ``` python


    from multiprocessing import Process,Queue
    q = Queue(3)  #3个长度的队列
    q.put(1)   #如果满了,阻塞程序
    q.get()    #如果没了,阻塞程序
    q.qsize()  #统计一下当前队列里面有多少个数据了
    q.empty()  #是否为空,不可信
    q.full()   #是否满了,不可信
    q.put_nowait('a')  #如果满了就报错,不等待  
    q.get_nowait() #如果没了就报错,不等待
    ```

    进程通过队列通信:

    ```python


    from multiprocessing import Process,Queue
    def f1(q):
        ret = q.get()
        print('子进程的ret>>',ret)
    
    if __name__ == '__main__':
        q = Queue(3)
        q.put('你好')
        p = Process(target=f1,args=(q,))
        p.start()
    ```


    ### 线程

    创建线程的两种方式

    ```python
    #方式1
    from threading import Thread
    def f1(n):
        pass
    
    if __name__ == '__main__':
        t = Thread(target=f,args=(1,))
        t.daemon = True  #守护线程
        t.start()
        t.join()
    #方式2:
    class MyThread(Thread):
        def __init__(self,n):
            super().__init__()
            self.n = n
        def run(self):
            print(self.n)
            pass
    if __name__ == '__main__':
        t = MyThread('aa')
        t.start()
    
    
    ```


    ##### 守护线程和守护进程的区别

    ```
    守护进程:随着主进程的代码执行结束,而结束
    守护线程:随着所有非守护线程的执行结束而结束
    ```


    #### 锁

    互斥锁 Lock

    ```python
    作用:多线程或者多进程在操作共享数据的时候,会出现数据混乱的问题,加锁处理,牺牲了效率,保证了安全.


    from threading import Thread,Lock
    from multiprocessing import Process,Lock
    def f1(loc):
        loc.acquire()
        xxxx
        loc.release()
        
        with loc:
            xxxxx
    
    loc = Lock()
    t = Thread(target=f1,args=(loc,))
    t.start()
    ```

    递归锁 RLock

    ```python
    死锁现象,内部维护了一个计数器


    from threading import Thread,RLock
    from multiprocessing import Process,RLock
    
    loc = RLock()
    t = Thread(target=f1,args=(loc,))
    t.start()
    ```



    线程队列:

    ```python


    import queue
    #先进先出的
    q = queue.Queue(4)
    ...
    #先进后出的
    q = queue.LifoQueue(4)
    #优先级的
    q = queue.PriorityQueue(4)
    q.put((1,'xx'))  #数字越小,优先级越高,越早被取出
    q.get() -- (1,'xx')
    如果优先级数字相同,后面的值类型不能不一样,而且两个字典也不能比
    ```



    线程池和进程池

    ```python


    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    #线程池ThreadPoolExecutor
    #进程池ProcessPoolExecutor
    
    def f1(n,m)
        pass
        return n*n
        
    def call_back(m):  m.result()--n*n
        print(m) #结果集对象
        print(m.result())
    
    pool = ThreadPoolExecutor(max_workers=5)
    pool = ProcessPoolExecutor(max_workers=5)
    ret = pool.submit(f1,1,2)
    ret.result()  #类似join,拿不到结果就阻塞程序
    pool.shutdown()  #关闭池子
    pool.submit(f1,1,2).add_done_callback(call_back)
    ```

    ### 协程

    ```python
    gevent --- 基于greenlet模块


    def f1(n):
        pass
    def f2(n):
        pass
    g1 = gevent.spawn(f1,1) 
    g2 = gevent.spawn(f2,1) 
    g1.join() #一个一个的join
    gevent.joinall([g1,g2])
    print('主任务')


    ```

    参考博客:

    ```python
    进程:https://www.cnblogs.com/clschao/articles/9629392.html
    线程:https://www.cnblogs.com/clschao/articles/9684694.html
    协程:https://www.cnblogs.com/clschao/articles/9712056.html
    ```


    
    
     
  • 相关阅读:
    Orchard学习 02、orchard 路由
    Orchard学习 01、orchard日志
    golang限制协程的最大开启数
    go爬取博客园
    go xpath 添加头部解析
    goadmin文档
    使用GoAdmin极速搭建golang应用管理后台
    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了)转
    自定义推荐央视
    python爬虫 xpath
  • 原文地址:https://www.cnblogs.com/lilyxiaoyy/p/10964077.html
Copyright © 2011-2022 走看看