• python之路 IO多路复用 线程进程初步了解


    一、IO多路复用

    1、客户端

    #!/usr/bin/env python
    #-*-coding:utf-8-*-
    import socket
    sk=socket.socket()
    sk.connect(('127.0.0.1',8888,))
    data=sk.recv(1024)
    print(data)
    while True:
        inp=input('>>>')
        sk.sendall(bytes(inp,encoding='utf-8'))
        print(sk.recv(1024))
    sk.close()

    2、服务端

    #!/usr/bin/env python
    #-*-coding:utf-8-*-
    import socket
    import select
    sk=socket.socket()
    sk.bind(('127.0.0.1',8888,))
    sk.listen(5)
    
    inputs=[sk,]
    outputs=[]
    messages={}
    #del messages[张三]
    #message={
    #   张三:[消息1,消息2]
    #       }
    while True:
        rlist,wlist,e,=select.select(inputs,outputs,[],1)
        print(len(inputs),len(rlist),len(wlist),len(outputs))
        #监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端连接了,此时rlist值为[sk]
        #监听conn对象,如果conn发生变化,表示客户端有新消息发送过来了,此时rlist的值为[客户端]
        for r in rlist:
            if r==sk:
                #新客户来连接
                conn,address=r.accept()
                #conn是什么?其实是socket对象
                inputs.append(conn)
                messages[conn]=[]
                conn.sendall(bytes('hello',encoding='utf-8'))
            else:
                #有人给我发消息
                # beta=r.recv(1024)
                print('==============')
                try:
                    ret=r.recv(1024)
                    if not ret:
                        raise Exception('断开连接')
                    else:
                        outputs.append(r)
                        messages[r].append(ret)
                except Exception as e:
                    inputs.remove(r)
                    del messages[r]
        #所有给我发过消息的人
        for w in wlist:
            msg=messages[w].pop()
            resp=msg+bytes('response',encoding='utf-8')
            w.sendall(resp)
            outputs.remove(w)

    二、线程

    Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import threading
    import time
      
    def show(arg):
        time.sleep(1)
        print 'thread'+str(arg)
      
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
      
    print 'main thread stop'

    上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。

    更多方法:

      • start            线程准备就绪,等待CPU调度
      • setName      为线程设置名称
      • getName      获取线程名称
      • setDaemon   设置为后台线程或前台线程(默认)
                           如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
                            如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
      • join              逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
      • run              线程被cpu调度后自动执行线程对象的run方法

    自定义类程序

    import threading
    import time
     
     
    class MyThread(threading.Thread):
        def __init__(self,num):
            threading.Thread.__init__(self)
            self.num = num
     
        def run(self):#定义每个线程要运行的函数
     
            print("running on number:%s" %self.num)
     
            time.sleep(3)
     
    if __name__ == '__main__':
     
        t1 = MyThread(1)
        t2 = MyThread(2)
        t1.start()
        t2.start()

    线程锁(Lock、RLock)

    由于线程之间是进行随机调度,并且每个线程可能只执行n条执行之后,当多个线程同时修改同一条数据时可能会出现脏数据,所以,出现了线程锁 - 同一时刻允许一个线程执行操作。

    未用锁:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import threading
    import time
    
    gl_num = 0
    
    def show(arg):
        global gl_num
        time.sleep(1)
        gl_num +=1
        print gl_num
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    
    print 'main thread stop'
    #!/usr/bin/env python
    #coding:utf-8
       
    import threading
    import time
       
    gl_num = 0
       
    lock = threading.RLock()
       
    def Func():
        lock.acquire()
        global gl_num
        gl_num +=1
        time.sleep(1)
        print gl_num
        lock.release()
           
    for i in range(10):
        t = threading.Thread(target=Func)
        t.start()
  • 相关阅读:
    TLS Version 1.0 Protocol Detection 漏洞修复
    更新ESXI版本
    CentOS7禁止PING的方法
    Nginx_ingress配置ssl_dhparam
    Nessus安装与使用
    centos7的防火墙不能控制docker容器端口的问题
    centos 7 安装mariadb
    CentOS7 ICMP漏洞修复
    如何基于LSMtree架构实现一写多读
    vitual box 安装centos7
  • 原文地址:https://www.cnblogs.com/zhangkui/p/5675218.html
Copyright © 2020-2023  润新知