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
python学习-并发编程(十四)的更多相关文章
- Python学习笔记(十四)
Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...
- Python学习笔记(十四):模块高级
以Mark Lutz著的<Python学习手册>为教程,每天花1个小时左右时间学习,争取两周完成. --- 写在前面的话 2013-7-23 21:30 学习笔记 1,包导入是把计算机上的 ...
- Python学习札记(三十四) 面向对象编程 Object Oriented Program 5
参考:获取对象信息 NOTE 1.type()函数可以用来判断对象的类型: >>> type(123) <class 'int'> >>> type(' ...
- Python学习札记(二十四) 函数式编程5 返回函数
参考:返回函数 NOTE 1.高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. eg.求和函数 #!/usr/bin/env python3 def calsums(*args): a ...
- day31 python学习 并发编程之多进程理论部分
一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): 二 进程与程序的区别 程序仅仅只是一堆代码而已,而进程指的是程序的运行 ...
- python学习笔记-(十四)进程&协程
一. 进程 1. 多进程multiprocessing multiprocessing包是Python中的多进程管理包,是一个跨平台版本的多进程模块.与threading.Thread类似,它可以利用 ...
- python学习笔记-(十四)I/O多路复用 阻塞、非阻塞、同步、异步
1. 概念说明 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可 ...
- 老男孩python学习自修第二十四天【多进程】
1. 体验多进程的运行速度 #!/usr/bin/env python # _*_ coding:UTF-8 _*_ from multiprocessing import Pool import t ...
- Python学习日记(二十四) 继承
继承 什么是继承?就是一个派生类(derived class)继承基类(base class)的字段和方法.一个类可以被多个类继承;在python中,一个类可以继承多个类. 父类可以称为基类和超类,而 ...
随机推荐
- 如何更规范化编写Java 代码
如何更规范化编写Java 代码 Many of the happiest people are those who own the least. But are we really so happy ...
- selenium-03-01截图函数
UI自动化测试执行过程中,当遇到检查失败的情况,往往会发现打印的log并不能有效地帮助我们定位问题.我们需要失败时刻的屏幕截图来重现当时的失败场景,进而排查出错原因. 基于这种需求可以使用Sele ...
- C# 时间戳的相关操作
一般的 时间戳 格式分为两种 即 10位(秒)时间戳 与 13位(毫秒)时间戳 时间戳 类型也分为两种 即 本地时间戳 与 世界统一(UTC)时间戳 废话不多说,直接上代码: 一.时间戳获取方法 // ...
- 十分钟快速学会Matplotlib基本图形操作
在学习Python的各种工具包的时候,看网上的各种教程总是感觉各种方法很多很杂,参数的种类和个数也十分的多,理解起来需要花费不少的时间. 所以我在这里通过几个例子,对方法和每个参数都进行详细的解释,这 ...
- Mysql高手系列 - 第21篇:什么是索引?
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 这是Mysql系列第21篇. 本文开始连续3篇详解mysql索引: 第1篇来说说什么是索引? 第2篇详解Mysql中 ...
- hover和position共用出现的问题
hover 鼠标移入的样式 position 定位属性 包含 relative 相对定位 absolute 绝对定位为 fixed 固定定位 hover作用范围 可以实现自己样式的 ...
- python串口助手
最近项目中要使用模拟数据源通过向外发送数据,以前都是用C#编写,最近在研究python,所以就用python写了一个串口助手,方便以后的测试. 在电脑上通过虚拟串口助手产生两个虚拟串口,运行编写的串口 ...
- Redis与数据库数据一致性
文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号. 可能谈到保持Redis与Mysql双库的数据一致性,可能很多人最先想到的方案就是读请求和写请求串行化,串到一个 ...
- linux无法安装应用
需安装flex 和bison 一般需要更新软件源 root权限 下 apt-get update apt-get upgrade 如果出现以下问题,先查看网络是否畅通: ping 192.168.0. ...
- Sublime text3 配置c++环境 并设置快捷键
VScode配c++环境太麻烦了 打算用sublime写C++ 记录一下配置过程因为我是有DEV环境的 直接将MINGW64加入环境变量即可 在DEV文件夹下的MinGW64\bin(就是有g++.e ...