• python学习-并发编程(十四)


    14.2线程的创建与启动

    import threading
    
    
    # 定义一个普通的action函数,该函数准备作为线程执行体
    def action(max):
        for i in range(max):
            print(threading.current_thread().getName() + " " + str(i))
    
    
    # 下面是主程序(也就是主线程的执行体)
    for i in range(100):
        print(threading.current_thread().getName() + " " + str(i))
        if i == 20:
            # 创建并启动第一个线程
            t1 = threading.Thread(target=action, args=(100,))
            t1.start()
            # 创建并启动第二个线程
            t2 = threading.Thread(target=action, args=(100,))
            t2.start()
    print('主线程执行完成!')
    
    
    输出结果:
    ...
    Thread-2 83
    MainThread 99
    Thread-1 81
    Thread-2 84
    主线程执行完成!
    Thread-1 82
    Thread-2 85
    Thread-1 83
    ...
    first_thread

    当python程序开始运行后,程序至少会创建一个主线程,主线程的线程执行体就是程序中的主程序-没有放在任何函数中的代码。

    以上程序共包含三个线程,这三个线程的执行没有先后顺序,它们以并发方式执行:Thread-1执行一段时间,然后Thread-2或MainThread获得cpu执行一段时间,接下来又换其他线程执行,这就是典型的线程并发执行-cpu以快速轮换的方式在多个线程之间切换,从而给用户一种错觉:多个线程似乎同时在执行。

    简言之,多线程就是让多个函数能并发执行,让普通用户感觉到多个函数似乎同时在执行。

    在默认情况下 主线程的字为 MainThread 用户 动的 线程的字依次为 Thread-1 、 Thread-2, Thread-3

    14.3线程的生命周期

    14.4控制线程

    import threading
    
    
    def action(max):
        for i in range(max):
            print(threading.current_thread().name + "" + str(i))
    
    
    threading.Thread(target=action, args=(100,), name="新线程").start()
    
    for i in range(100):
        if i == 20:
            jt = threading.Thread(target=action, args=(100,), name="被join的线程")
            jt.start()
            jt.join()
        print(threading.current_thread().name + "" + str(i))
    
    输出结果:
    ...
    MainThread19
    新线程20
    新线程21
    新线程22
    新线程23
    被join的线程0
    新线程24
    被join的线程1
    ...
    join_thread

    主线程执行到 i==20 时,程序启动“被join的线程”,所以主线程将一直处于阻塞状态,直到“被join的线程”执行完成。

    import threading
    
    
    def action(max):
        for i in range(max):
            print(threading.current_thread().name + "" + str(i))
    t = threading.Thread(target=action,args=(100,),name="后台进程")
    t.daemon = True  # 必须在start()前设置
    t.start()
    for i in range(10):
        print(threading.current_thread().name + "" + str(i))
    
    输出结果:
    后台进程0
    MainThread0
    后台进程1
    MainThread1
    后台进程2
    MainThread2
    后台进程3
    MainThread3
    MainThread4
    后台进程4
    MainThread5
    后台进程5
    MainThread6
    后台进程6
    MainThread7
    后台进程7
    MainThread8
    后台进程8
    MainThread9
    后台进程9
    daemon_thread(后台进程或守护进程)

    如果所有前台线程死亡,那么后台线程会自动死亡。

    import time
    
    for i in range(4):
        print("当前时间:%s" % time.ctime())
        time.sleep(1) # 调用sleep()函数让线程暂停1s
    
    输出结果:
    当前时间:Thu Oct 10 22:34:24 2019
    当前时间:Thu Oct 10 22:34:25 2019
    当前时间:Thu Oct 10 22:34:26 2019
    当前时间:Thu Oct 10 22:34:27 2019
    线程睡眠:sleep

    14.5线程同步

    14.6线程通信

    14.7线程池

    线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它,当该函数执行结束后,该线程并不会死亡,而是再返回到线程池中变成空闲状态,等待执行下一个函数。

    14.8线程相关类

    定时器

    from threading import Timer
    
    
    def hello():
        print("hello world!")
    
    
    t = Timer(10.0, hello)  # 使用Timer控制10s后执行hello函数
    t.start()
    Timer1
    from threading import Timer
    import time
    
    # 定义总共输出几次的计数器
    count = 0
    def print_time():
        print("当前时间:%s" % time.ctime())
        global t, count
        count += 1
        # 如果count小于10,开始下一次调度
        if count < 10:
            t = Timer(1, print_time)
            t.start()
    # 指定1秒后执行print_time函数
    t = Timer(1, print_time)
    t.start()
    
    输出结果:
    当前时间:Thu Oct 10 23:11:09 2019
    当前时间:Thu Oct 10 23:11:10 2019
    当前时间:Thu Oct 10 23:11:11 2019
    当前时间:Thu Oct 10 23:11:12 2019
    当前时间:Thu Oct 10 23:11:13 2019
    当前时间:Thu Oct 10 23:11:14 2019
    当前时间:Thu Oct 10 23:11:15 2019
    当前时间:Thu Oct 10 23:11:16 2019
    当前时间:Thu Oct 10 23:11:17 2019
    当前时间:Thu Oct 10 23:11:18 2019
    Timer2

    上面程序开始运行后,程序控制 l s 后执行 print_time()函数 print_time()函数中的粗体字代码
    判断 如果 count 小10 ,程序再次使用 Timer 调度 ls 后执行 print_time()函数,这样就可以控制
    print_time()函数多次重复执行

    任务调度

    import sched, time
    import threading
    
    # 定义线程调度器
    s = sched.scheduler()
    
    # 定义被调度的函数
    def print_time(name='default'):
        print("%s 的时间: %s" % (name, time.ctime()))
    print('主线程:', time.ctime())
    # 指定10秒之后执行print_time函数
    s.enter(10, 1, print_time)
    # 指定5秒之后执行print_time函数,优先级为2
    s.enter(5, 2, print_time, argument=('位置参数',))
    # 指定5秒之后执行print_time函数,优先级为1
    s.enter(5, 1, print_time, kwargs={'name': '关键字参数'})
    # 执行调度的任务
    s.run()
    print('主线程:', time.ctime())
    
    输出结果:
    主线程: Thu Oct 10 23:18:27 2019
    关键字参数 的时间: Thu Oct 10 23:18:32 2019
    位置参数 的时间: Thu Oct 10 23:18:32 2019
    default 的时间: Thu Oct 10 23:18:37 2019
    主线程: Thu Oct 10 23:18:37 2019
    sched
  • 相关阅读:
    项目经验总结
    聚合,组合之间的关系(aggregate,composite)
    做策划方案遇到问题
    给公司员工上的培训1——微观规范
    关于Oracle的简单导入导出
    SVN服务管理配置(原创,引用请注明出处)
    面向功能开发一点经验
    SourceMonitor使用手记
    泡泡、搜房、方正我该如何选择
    Excel 关联 合并 上海
  • 原文地址:https://www.cnblogs.com/wang-mengmeng/p/11650731.html
Copyright © 2020-2023  润新知