14.2线程的创建与启动

  1. import threading
  2.  
  3. # 定义一个普通的action函数,该函数准备作为线程执行体
  4. def action(max):
  5. for i in range(max):
  6. print(threading.current_thread().getName() + " " + str(i))
  7.  
  8. # 下面是主程序(也就是主线程的执行体)
  9. for i in range(100):
  10. print(threading.current_thread().getName() + " " + str(i))
  11. if i == 20:
  12. # 创建并启动第一个线程
  13. t1 = threading.Thread(target=action, args=(100,))
  14. t1.start()
  15. # 创建并启动第二个线程
  16. t2 = threading.Thread(target=action, args=(100,))
  17. t2.start()
  18. print('主线程执行完成!')
  19.  
  20. 输出结果:
  21. ...
  22. Thread-2 83
  23. MainThread 99
  24. Thread-1 81
  25. Thread-2 84
  26. 主线程执行完成!
  27. Thread-1 82
  28. Thread-2 85
  29. Thread-1 83
  30. ...

first_thread

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

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

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

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

14.3线程的生命周期

14.4控制线程

  1. import threading
  2.  
  3. def action(max):
  4. for i in range(max):
  5. print(threading.current_thread().name + "" + str(i))
  6.  
  7. threading.Thread(target=action, args=(100,), name="新线程").start()
  8.  
  9. for i in range(100):
  10. if i == 20:
  11. jt = threading.Thread(target=action, args=(100,), name="被join的线程")
  12. jt.start()
  13. jt.join()
  14. print(threading.current_thread().name + "" + str(i))
  15.  
  16. 输出结果:
  17. ...
  18. MainThread19
  19. 新线程20
  20. 新线程21
  21. 新线程22
  22. 新线程23
  23. join的线程0
  24. 新线程24
  25. join的线程1
  26. ...

join_thread

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

  1. import threading
  2.  
  3. def action(max):
  4. for i in range(max):
  5. print(threading.current_thread().name + "" + str(i))
  6. t = threading.Thread(target=action,args=(100,),name="后台进程")
  7. t.daemon = True # 必须在start()前设置
  8. t.start()
  9. for i in range(10):
  10. print(threading.current_thread().name + "" + str(i))
  11.  
  12. 输出结果:
  13. 后台进程0
  14. MainThread0
  15. 后台进程1
  16. MainThread1
  17. 后台进程2
  18. MainThread2
  19. 后台进程3
  20. MainThread3
  21. MainThread4
  22. 后台进程4
  23. MainThread5
  24. 后台进程5
  25. MainThread6
  26. 后台进程6
  27. MainThread7
  28. 后台进程7
  29. MainThread8
  30. 后台进程8
  31. MainThread9
  32. 后台进程9

daemon_thread(后台进程或守护进程)

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

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

线程睡眠:sleep

14.5线程同步

14.6线程通信

14.7线程池

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

14.8线程相关类

定时器

  1. from threading import Timer
  2.  
  3. def hello():
  4. print("hello world!")
  5.  
  6. t = Timer(10.0, hello) # 使用Timer控制10s后执行hello函数
  7. t.start()

Timer1

  1. from threading import Timer
  2. import time
  3.  
  4. # 定义总共输出几次的计数器
  5. count = 0
  6. def print_time():
  7. print("当前时间:%s" % time.ctime())
  8. global t, count
  9. count += 1
  10. # 如果count小于10,开始下一次调度
  11. if count < 10:
  12. t = Timer(1, print_time)
  13. t.start()
  14. # 指定1秒后执行print_time函数
  15. t = Timer(1, print_time)
  16. t.start()
  17.  
  18. 输出结果:
  19. 当前时间:Thu Oct 10 23:11:09 2019
  20. 当前时间:Thu Oct 10 23:11:10 2019
  21. 当前时间:Thu Oct 10 23:11:11 2019
  22. 当前时间:Thu Oct 10 23:11:12 2019
  23. 当前时间:Thu Oct 10 23:11:13 2019
  24. 当前时间:Thu Oct 10 23:11:14 2019
  25. 当前时间:Thu Oct 10 23:11:15 2019
  26. 当前时间:Thu Oct 10 23:11:16 2019
  27. 当前时间:Thu Oct 10 23:11:17 2019
  28. 当前时间:Thu Oct 10 23:11:18 2019

Timer2

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

任务调度

  1. import sched, time
  2. import threading
  3.  
  4. # 定义线程调度器
  5. s = sched.scheduler()
  6.  
  7. # 定义被调度的函数
  8. def print_time(name='default'):
  9. print("%s 的时间: %s" % (name, time.ctime()))
  10. print('主线程:', time.ctime())
  11. # 指定10秒之后执行print_time函数
  12. s.enter(10, 1, print_time)
  13. # 指定5秒之后执行print_time函数,优先级为2
  14. s.enter(5, 2, print_time, argument=('位置参数',))
  15. # 指定5秒之后执行print_time函数,优先级为1
  16. s.enter(5, 1, print_time, kwargs={'name': '关键字参数'})
  17. # 执行调度的任务
  18. s.run()
  19. print('主线程:', time.ctime())
  20.  
  21. 输出结果:
  22. 主线程: Thu Oct 10 23:18:27 2019
  23. 关键字参数 的时间: Thu Oct 10 23:18:32 2019
  24. 位置参数 的时间: Thu Oct 10 23:18:32 2019
  25. default 的时间: Thu Oct 10 23:18:37 2019
  26. 主线程: Thu Oct 10 23:18:37 2019

sched

python学习-并发编程(十四)的更多相关文章

  1. Python学习笔记(十四)

    Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...

  2. Python学习笔记(十四):模块高级

    以Mark Lutz著的<Python学习手册>为教程,每天花1个小时左右时间学习,争取两周完成. --- 写在前面的话 2013-7-23 21:30 学习笔记 1,包导入是把计算机上的 ...

  3. Python学习札记(三十四) 面向对象编程 Object Oriented Program 5

    参考:获取对象信息 NOTE 1.type()函数可以用来判断对象的类型: >>> type(123) <class 'int'> >>> type(' ...

  4. Python学习札记(二十四) 函数式编程5 返回函数

    参考:返回函数 NOTE 1.高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. eg.求和函数 #!/usr/bin/env python3 def calsums(*args): a ...

  5. day31 python学习 并发编程之多进程理论部分

    一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): 二 进程与程序的区别 程序仅仅只是一堆代码而已,而进程指的是程序的运行 ...

  6. python学习笔记-(十四)进程&协程

    一. 进程 1. 多进程multiprocessing multiprocessing包是Python中的多进程管理包,是一个跨平台版本的多进程模块.与threading.Thread类似,它可以利用 ...

  7. python学习笔记-(十四)I/O多路复用 阻塞、非阻塞、同步、异步

    1. 概念说明 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可 ...

  8. 老男孩python学习自修第二十四天【多进程】

    1. 体验多进程的运行速度 #!/usr/bin/env python # _*_ coding:UTF-8 _*_ from multiprocessing import Pool import t ...

  9. Python学习日记(二十四) 继承

    继承 什么是继承?就是一个派生类(derived class)继承基类(base class)的字段和方法.一个类可以被多个类继承;在python中,一个类可以继承多个类. 父类可以称为基类和超类,而 ...

随机推荐

  1. 48 (OC)* 适配iPad和iPhone、以及横竖屏适配。

    一:核心方法 1.三个方法 1.1:开始就会触发 - (void)viewWillLayoutSubviews; 1.2:开始就会触发 - (void)viewDidLayoutSubviews; 1 ...

  2. Moonraker 靶机渗透

    0x01 简介 攻击Moonraker系统并且找出存在最大的威胁漏洞,通过最大威胁漏洞攻击目标靶机系统并进行提权获取系统中root目录下的flag信息. Moonraker: 1镜像下载地址: htt ...

  3. JSP自定义标签的使用简化版

    在jsp中 如果不想页面中出现java代码 这个时候就需要使用到jsp的自定义标签库技术了 自定义标签库 能够有效的减少jsp中java代码的出现 使其更加自然的像html页面一样 如果要使用jsp自 ...

  4. vue-router路由元信息及keep-alive组件级缓存

    路由元信息?(黑人问号脸???)是不是这么官方的解释很多人都会一脸懵?那么我们说meta,是不是很多人恍然大悟,因为在项目中用到或者看到过呢? 是的,路由元信息就是我们定义路由时配置的meta字段:那 ...

  5. easyui-datetimebox 控件绑定双击事件实现自动选中当前日期时间

    本方法是在不改变原 js 的情况下,通过扩展方法来实现本目的 首先在 datetimebox 控件中扩展一个 绑定双击事件 的方法 $.extend($.fn.datetimebox.methods, ...

  6. C#实现请求唯一性校验支持高并发

    使用场景描述: 网络请求中经常会遇到发送的请求,服务端响应是成功的,但是返回的时候出现网络故障,导致客户端无法接收到请求结果,那么客户端程序可能认为判断为网络故障,而重复发送同一个请求.当然如果接口中 ...

  7. chown、chgrp、chmod

    1.权限对应的数值 一开始理解权限对应的数值总是要去用二进制去算例如r-x是多少rwx是多少,后来才知道r就 是4,w就是2,x就是1,不管权限怎么变,他们对应的数值就是对应位相加.. 权限对于文件来 ...

  8. VR中的Redirection

    在虚拟现实(Virtual Reality,VR)中,很重要的一点就是用户的在虚拟环境中的漫游(navigation).除了固定视点的VR电影,一般的VR应用,特别是游戏或者其他交互式的应用,都会依赖 ...

  9. python Django中的cookie和session

    目录 Cookie 1.1获取Cookie 1.2设置Cookie Session 1.数据库Session 2.缓存Session 3.文件Session 4.缓存+数据库Session Cooki ...

  10. 校园网 虚拟机VMware Linux桥接模式 无法上网 问题

    只是解决常见虚拟机桥接模式 无法上网问题,基本的百度都有 基本知识 虚拟机有三种网络连接模式:桥接模式,net模式,仅主机 桥接模式:同一网段允许的话,相当于一个独立的物理主机,独立ip net模式: ...