多任务

作者: 嘤嘤嘤998 | 来源:发表于2019-05-13 11:23 被阅读0次
    • 并行:真的多任务
      并发:假的多任务

    普通解释:
    并发:交替做不同事情的能力
    并行:同时做不同事情的能力
    专业术语:
    并发:不同的代码块交替执行
    并行:不同的代码块同时执行

    解释一:并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
    解释二:并行是在不同实体上的多个事件,并发是在同一实体上的多个事件。

    例子:
    - 顺序执行:你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
    - 并发:你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
    - 并行:你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并

    线程

    • 创建线程:
    • 通过继承Thread类完成创建线程:
    • 多线程共享全局变量(子线程与子线程,子线程与主线程,都共享):
    • 多线程会资源竞争:

      解决资源竞争:互斥锁 互斥锁的另一种锁法:
    • 死锁:
    • 多线程版udp聊天器(同时实现收和发)

      做两个线程,一个while True收,一个while True发:
    • 查看进程数:

    进程

    • 线程 vs 进程:
    • Queue:
      通过Queue完成进程间通信:
    • 进程池:
    • 多任务文件夹copy:
      进度条实现:

    协程

    • 迭代器(一个拥有iter() 和 next() 的class类):
      迭代器只在内存中保存生成数据的代码,用的时候随时调用,不需要存储大量数据
    • 迭代逐一获取Classmate里的name: 上例把Classmate和ClassIterator合并也可以:
    • 斐波那契

      列表实现: 函数实现:
      迭代器实现斐波那契:

    生成器

    函数中有yield语句的就是生成器,生成器可以让代码暂停执行,并保留结果,等到下一次next调用时再继续执行 上图打印结果:
    生成器实现斐波那契: 生成器的返回值:
    • send方式: 输出结果:
      yield实现多任务(一般不使用yield): image.png
    • gevent实现多任务(多任务一般都是使用gevent):

      gevent遇到延时就会继续执行下一个任务
      gevent实现多任务下载器:
    • 返回固定页面的HTTP服务器:

    import socket
    import multiprocessing
    import threading
    # 协程
    import gevent
    from gevent import monkey
    monkey.patch_all()
    
    
    
    def service_client(new_socket):
        request = new_socket.recv(1024)
        print(request)
    
        response = "HTTP/1.1 200 OK\r\n"
        response += "\r\n"
        response += "hahaha"
        new_socket.send(response.encode("utf-8"))
    
        new_socket.close()
    
    
    def main():
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置当服务器先close,即服务器端4次挥手之后资源能够立即释放,以保证下次运行程序时能立即执行
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        tcp_server_socket.bind("", 7890)
        tcp_server_socket.listen(128)
    
        while True:
            new_socket, client_addr = tcp_server_socket.accept()
    
            # 简单web服务器实现
            service_client(new_socket)
    
            # 并发web服务器实现
            p = multiprocessing.Process(target=service_client, args=(new_socket, ))
            p.start()
            new_socket.close()
    
            # 并发web服务器实现 多线程实现
            t = threading.Thread(target=service_client, args=(new_socket, ))
            t.start()
    
            # 并发web服务器实现 协程实现
            gevent.spawn(service_client, new_socket)
    
        tcp_server_socket.close()
    
    
    if __name__ == '__main__':
        main()
    
    • 三次握手,四次挥手:
    • 单进程,单线程,非堵塞实现并发:
      accept 和 recv 都会堵塞

    import socket
    
    
    def main():
    
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
        tcp_server_socket.setblocking(False)  # 设置套接字为非堵塞的方式
        
        tcp_server_socket.bind("", 7890)
        tcp_server_socket.listen(128)
    
        client_socket_list = list()
    
        while True:
            try:
                new_socket, new_addr = tcp_server_socket.accept()
            except Exception as ret:
                print("没有客户端连接")
            else:
                new_socket.setblocking(False)   # 设置套接字为非堵塞的方式
                client_socket_list.append(new_socket)
    
            for client_socket in client_socket_list:
                try:
                    recv_data = client_socket.recv(1024)  # 如果client没有发送数据过来,这句会异常,进入except
                except Exception as ret:
                    print("客户端没有数据传过来")
                else:
                    if recv_data:
                        print("客户端传递了数据过来")
                    else:   # 当client调用了close,会发送空数据过来,即recv_data为空
                        client_socket_list.remove(client_socket)
                        client_socket.close()
    
    
    if __name__ == '__main__':
        main()
    
    • 长连接 短连接
    • epoll
      epoll实现

    相关文章

      网友评论

          本文标题:多任务

          本文链接:https://www.haomeiwen.com/subject/fzffaqtx.html