• 多线程(1)


    1. 线程内容

    '''
    初识别线程
    在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程,cpu真正的执行单位是线程
    在工厂中,每个车间都有房子,而且每个车间默认就有一条流水线
    
    操作系统 ===》工厂
    进程 ===》车间
    线程 ===》流水线
    cpu ===》电源
    
    线程:cpu最小的执行单位
    进程:资源集合/资源单位
    线程运行 = 运行代码
    进程运行 = 各种资源 + 线程
    
    右键运行:
    申请内存空间,先把解释器丢进去并且把代码丢进去,运行代码(线程)
    
    进程和线程的区别:
    
    过程描述的区别
    线程 ==》单指代码的执行过程
    进程 ==》资源的申请与销毁的过程
    
    进程内存空间彼此隔离
    同一个进程下的线程共享资源
    
    进程和线程的创建速度
    进程需要申请资源开辟空间  慢
    只是告诉操作系统一个执行方案
    '''
    

    2. 线程开启的两种方式

    # 方式一
    from threading import Thread
    import time
    
    def task():
        print('线程 start')
        time.sleep(2)
        print('线程 end')
    
    if __name__ == '__main__':
        t = Thread(target=task)
        t.start()   # 告诉操作系统开一个线程 开启线程无需申请内存空间会非常快
        print('主')
    
    
    # 1 同一个进程下没有父子线程之分大家地位都一样。
    # 2 右键运行发生了什么事情?开启了一个进程,开辟了一个内存空间,把代码都丢进去,然后运行代码(自带的主线程运行),然后又开启了一个子线程。
    
    # 主线程结束和子线程结束没有任何必然联系,比如主线程运行结束,子线程还在运行当中。不是主线程在等待子线程结束,是进程在等待自己的所有线程结束。
    
    
    # 方式二
    from threading import Thread
    import time
    # 进程等待所有线程结束才会结束
    
    class Myt(Thread):
        def run(self):
            print('子线程 start')
            time.sleep(2)
            print('子线程 end')
    
    # if __name__ == '__main__':
    t = Myt()
    t.start()
    print('主线程')
    

    3. 进程vs线程创建速度

    from threading import Thread
    from multiprocessing import Process
    import time
    
    def task(name):
        print(f'{name} is running')
        time.sleep(3)
        print(f'{name} is end')
    
    if __name__ == '__main__':
        t = Thread(target=task,args=('子线程',))
        p = Process(target=task,args=('子进程',))
        t.start()
        p.start()
        print('主')
    
    
    '''
    开启子线程的打印效果:
    子线程 is running
    主
    子线程 is end
    
    开启子进程的打印效果:
    主
    子进程 is running
    子进程 is end
    
    进程和线程的创建速度
    开启子进程需要申请资源开辟空间  慢
    开启子线程只是告诉操作系统一个执行方案  快
    '''
    

    4. 子线程共享资源

    from threading import Thread
    import time,os
    
    x = 100
    def task():
        global x
        x = 50
        print(os.getpid())  # 1816
    
    if __name__ == '__main__':
        t = Thread(target=task)
        t.start()
        time.sleep(2)
        print(x)  # 50
        print(os.getpid())  # 1816
    
    # 首先子线程修改了全局变量为50,主线程等待子线程修改完毕后打印x为50
    # 说明同一个进程下所有的线程共享同一份内存空间
    # 主进程下的每个线程都跟主进程的pid一样
    

    5. 线程的join方法

    from threading import Thread
    import time
    
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程 end')
    
    t = Thread(target=task)
    t.start()
    t.join()  # 主线程等待子线程运行结束
    print('主线程')
    
    # 进程的join是当前线程在等子进程运行结束并不影响其他线程
    
    
    from threading import Thread
    import time
    
    def task(name,n):
        print(f'{name} start')
        time.sleep(n)
        print(f'{name} end')
    
    t1 = Thread(target=task,args=('线程1',1))
    t2 = Thread(target=task,args=('线程2',2))
    t3 = Thread(target=task,args=('线程3',3))
    start = time.time()
    t1.start()
    t2.start()
    t3.start()
    t1.join()  # 1s
    t2.join()  # 1s
    t3.join()  # 1s
    end = time.time()
    print(end - start)   # 3.002460479736328
    
    # 在单核的情况下,多个线程是如何利用cpu的???
    

    6. 了解进程的join

    from multiprocessing import Process
    from threading import Thread
    import time
    
    def task1():
        print('进程 start')
        time.sleep(5)
        print('进程 end')
    
    def task2():
        print('子线程 start')
        time.sleep(2)
        print('子线程 end')
    
    if __name__ == '__main__':
        p = Process(target=task1)
        t = Thread(target=task2)
        t.start()   # 开线程
        p.start()   # 开进程
        print('子进程join开始')
        p.join()  # 主进程的主线程等待子进程运行结束  当前线程等待当前进程下的子进程结束,然后往下运行
        print('主')
    

    7. 线程其他相关用法

    from threading import Thread,currentThread,enumerate,activeCount
    import time
    
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程 end')
        print(enumerate())     # 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
        # print(currentThread(),'子线程')  # 返回当前的线程变量
    
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task)
        t1.start()
        t2.start()
    
        print(t1.is_alive())   # True  # 返回线程是否活动的
        print(t1.getName())    # Thread-1  # 返回线程名
        print(t2.getName())    # Thread-2  # 返回线程名
        t1.setName('班长')     # 设置线程名
        print(t1.getName())    # 班长
        print(currentThread().name)   # MainThread
        print(enumerate())   # [<_MainThread(MainThread, started 14420)>, <Thread(班长, started 3260)>, <Thread(Thread-2, started 10844)>]
        print(activeCount())   # 3    # 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果
        print(len(enumerate()))  # 3
    

    8. 守护线程

    # 守护线程 守护的是进程的运行周期
    '''
    守护线程首先是一个线程
        守护线程守护到当前进程运行结束
        有未完成的子进程阶段会守护
        有未完成的其他子线程也均会守护
    
    守护进程首先是一个进程
        守护进程守护到当前进程的最后一行代码结束
    '''
    from threading import Thread,enumerate,currentThread
    import time
    
    def task1():
        print('守护线程 start')
        print(currentThread())
        time.sleep(10)
        print('守护线程 end')
    
    def task2():
        print('子线程 start')
        time.sleep(5)
        print(enumerate())
        print('子线程 end')
    
    if __name__ == '__main__':
        t1 = Thread(target=task1)
        t2 = Thread(target=task2)
        t1.daemon = True
        t2.start()
        t1.start()
        print('主')
    
    # 当主线程已经结束的时候,其他子线程没有结束的时候打印当前的活跃的线程发现有守护线程
    
  • 相关阅读:
    帝国 标签模板 使用程序代码 去除html标记 并 截取字符串
    iis6 伪静态 iis配置方法 【图解】
    您来自的链接不存在 帝国CMS
    帝国cms Warning: Cannot modify header information headers already sent by...错误【解决方法】
    .fr域名注册 51元注册.fr域名
    帝国网站管理系统 恢复栏目目录 建立目录不成功!请检查目录权限 Godaddy Windows 主机
    星外虚拟主机管理平台 开通数据库 出现Microsoft OLE DB Provider for SQL Server 错误 '8004' 从字符串向 datetime 转换失败
    ASP.NET 自定义控件学习研究
    CSS层叠样式表之CSS解析机制的优先级
    ASP.NET程序员工作面试网络收藏夹
  • 原文地址:https://www.cnblogs.com/yushan1/p/11534876.html
Copyright © 2020-2023  润新知