zoukankan      html  css  js  c++  java
  • 线程

    线程

    一、初识线程

    1.1 什么是线程

    操作系统 —— 工厂
    进程 —— 车间
    线程—— 流水线
    cpu —— 电源
    线程:cpu最小的执行单位
    进程:资源集合/资源单位
    线程运行 = 运行代码
    进程运行 = 各种资源 + 线程

    1.2 线程和进程的区别

    线程 进程
    同一个进程下的线程资源共享 内存空间彼此隔离
    快:只是告诉操作系统一个执行方案 慢:需要申请资源开辟空间

    二、开启线程的两种方式

    '''方式一'''
    from threading import  Thread
    import time
    
    def task():
        print('子线程开始')
        time.sleep(1)
        print('子线程结束')
    
    if __name__ == '__main__':
        t = Thread(target=task)   #初始化一个对象
        t.start()
        time.sleep(2)
        print('主线程结束')
    
    '''方式二'''
    from threading import  Thread
    import time
    
    class task(Thread):
        print('子线程开始')
        time.sleep(1)
        print('子线程结束')
    
    t = task()
    t.start()
    time.sleep(2)
    print('主线程结束')
    

    三、线程与进程的速度对比

    from multiprocessing import Process
    from threading import Thread
    import time
    
    def task(name):
        print(f"{name}在运行")
        time.sleep(3)
        print(f"{name}结束")
    
    if __name__ == '__main__':
        p = Process(target=task,args=('子进程',))
        t = Thread(target=task,args=('子线程',))
        p.start()
        t.start()
        time.sleep(5)
        print('主')
        
    '''
    子线程在运行
    子进程在运行
    子线程结束
    子进程结束
    主
    ### 充分证明了线程比进程快
    '''
    

    四、证明子线程共享资源

    from threading import Thread
    
    
    x = 100
    def task():
        global x
        x = 1
    
    if __name__ == '__main__':
        t = Thread(target=task)
        t.start()
    print(x)  #如果x被改为1,则证明子线程共享资源  #1
    '''
    综上所述,充分证明子线程共享资源
    '''
    

    五、线程的相关方法

    5.1 join方法

    等待子线程运行结束

    '''join 方法'''
    
    from threading import Thread
    import time
    
    def task(name,n):
        print(f'{name}开始')
        time.sleep(n)
        print(f'{name}结束')
    
    if __name__ == '__main__':
        t1 = Thread(target=task,args=('子线程1',1))
        t2 = Thread(target=task,args=('子线程2',2))
        t3 = Thread(target=task,args=('子线程3',3))
    
        l = [t1,t2,t3]
        for t in l:
            t.start()
        t.join()  #感知子线程的结束 
        print('主线程结束')
        print(t.is_alive())  #查看t线程是否还活着,false 证明死了
    

    5.2 其他方法

    '''
    
    Thread实例对象的方法
      # isAlive(): 返回线程是否活动的。
      # getName(): 返回线程名。
      # setName(): 设置线程名。
    
    threading模块提供的一些方法(这些模块需要提前导入):
      # threading.currentThread(): 返回当前的线程变量。
      # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
      # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
    '''
    
    from  threading import Thread,current_thread,enumerate,active_count
    import time
    
    def task(name,n):
        print(f'{name}开始')
        time.sleep(n)
        print(f'{name}结束')
    
    if __name__ == '__main__':
        t1 = Thread(target=task,args=('子线程1',1))
        t2 = Thread(target=task,args=('子线程2',2))
    
        l = [t1,t2]
        for t in l:
            t.start()
        print(t1.is_alive())  # 查看t1线程是否还活着  #True证明还活着
        print(t1.getName())  #获取t1线程名
        t1.setName('大猪蹄子线程')
        print(t1.getName())  #获取修改后的t1线程名
        print(current_thread())  # 返回当前线程
        print(enumerate())   #返回当前运行的线程的一个列表
        print(active_count())  #返回当前正在运行的线程数量
        t.join()
        print('主线程结束')
    '''
    子线程1开始
    子线程2开始
    True
    Thread-1
    大猪蹄子线程
    <_MainThread(MainThread, started 13384)>
    [<_MainThread(MainThread, started 13384)>, <Thread(大猪蹄子线程, started 1736)>, <Thread(Thread-2, started 10788)>]
    3
    子线程1结束
    子线程2结束
    主线程结束
    '''
    

    六、守护线程

    守护线程守护的是进程的运行周期

    • 对主进程来说,运行完毕指的是主进程代码运行完毕
    • 对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
    from threading import  Thread
    import time
    
    def task1():
        print('守护线程1开始')
        time.sleep(2)
        print('守护线程1结束')
        print(t1.is_alive())  #   True 当守护线程1结束了,守护线程1并没有死亡,也是在等待其他线程运行完毕
    
    def task2():
        print('子线程2开始')
        time.sleep(3)
        print('子线程2结束')
        print(t1.is_alive())  # false 当子线程2结束了,守护线程1就死了
    
    
    if __name__ == '__main__':
        t1 = Thread(target=task1)   #初始化一个对象
        t2 = Thread(target=task2)   #初始化一个对象
        t1.daemon = True  #必须在start开始之前将它设置为守护进程
        t1.start()
        t2.start()
        time.sleep(2)
        print('主线程结束')
        print(t1.is_alive())  #True  他没有因为主线程的结束而结束,而是等待子线程2运行完毕
        
    '''
    守护线程1开始
    子线程2开始
    主线程结束
    True
    守护线程1结束
    True
    子线程2结束
    False
    '''
    

    七、多线程实现socket

    '''服务器'''
    import socket
    from threading import Thread
    sk_s = socket.socket()  #实例化
    sk_s.bind(('127.0.0.1',8080))  #绑定
    sk_s.listen(5)  #监听
    
    def task(conn):  #子线程
        while True:  #通信循环
            msg = conn.recv(1024)   #接收线程
            conn.send(msg.upper())  #发送数据
    
    if __name__ == '__main__':
        while True:  # 链接循环
            print('等待客户端连接>>>>')
            conn, addr = sk_s.accept()  #等待接收
            print(f'客户端{addr}连接成功')
            t = Thread(target=task,args=(conn,))  #实例化一个线程t
            t.start()  #子线程开始
    
    '''客户端'''
    import socket
    sk_c = socket.socket()
    
    sk_c.connect(('127.0.0.1',8080))
    
    while True:
        msg = input('>>>').strip()
        if msg == "q":
            break
        msg = msg.encode('utf8')
        sk_c.send(msg)
        data = sk_c.recv(1024)
        print(data.decode('utf8'))
    
    sk_c.close()
    
  • 相关阅读:
    江湖盛传“阿里三板斧”,其实这才是全部真相!
    PHP算法之四大基础算法
    PHP实现的毫秒定时器,同时解决进程不重复堆积
    leetcode小题解析
    PHP算法之二分查找
    elastic学习笔记
    php中mysqli 处理查询结果集总结
    PHP中的 Iterator 与 Generator
    Laravel源码解析之反射的使用
    PHP下的异步尝试四:PHP版的Promise
  • 原文地址:https://www.cnblogs.com/yanjiayi098-001/p/11535169.html
Copyright © 2011-2022 走看看