zoukankan      html  css  js  c++  java
  • 多线程(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('主')
    
    # 当主线程已经结束的时候,其他子线程没有结束的时候打印当前的活跃的线程发现有守护线程
    
  • 相关阅读:
    Python3之json模块
    How To Enable EPEL Repository in RHEL/CentOS 7/6/5?
    安装CentOS 6.x出现Disk sda contains BIOS RAID metadata
    详解hdparm: linux下的硬盘测速工具
    {转载}需要同时设置 noatime 和 nodiratime 吗?
    ubuntu17.10安装LAMP并测试部署php探针系统
    shell监控网卡状态,故障时自动重启网卡
    L2TP/IPSec一键安装脚本
    Linux系统下用find命令查找最近修改过的文件
    Hyper-V 手动导入虚机配置实例(转载)
  • 原文地址:https://www.cnblogs.com/yushan1/p/11534876.html
Copyright © 2011-2022 走看看