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学习-并发编程(十四)的更多相关文章

  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. 06: RGB、YUV和HSV颜色空间模型

    RGBA是代表Red(红色)Green(绿色)Blue(蓝色)和Alpha的色彩空间 YUV:Y"表示明亮度(Luminance或Luma),也就是灰阶值:而"U"和&q ...

  2. 2019年9月3日安卓凯立德全分辨率(路况)夏季版C3551-C7M24-3K21J25懒人包

    拷贝懒人包NaviOne文件夹到机器根目录或内存卡根目录下:安装其中的apk程序 2019凯立德C3551-C7M24-3K21J25新组合懒人包 [分辨率]:自适应 [适用系统]:Android2. ...

  3. mybatis无法给带有下划线属性赋值问题

    https://blog.csdn.net/qq_33768099/article/details/69569561

  4. github认证登陆

    使用github OAuth实现用户登录 做登录功能时,允许使用第三方网站的身份,这称为"第三方登录". 原理 github内的认证方法 在github上申请OAuth App,进 ...

  5. adb命令整理(持续整理)

    用到过的adb命令都整理下来,省的一直百度,还不一定能找到合适的答案 获得正在运行app的包名 :adb shell dumpsys window | findstr mCurrentFocus 1. ...

  6. 第六届蓝桥杯java b组第十题

    10.压缩变换(程序设计) 小明最近在研究压缩算法. 他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比. 然而,要使数值很小是一个挑战. 最近,小明需要压缩一些正整数的序列,这些 ...

  7. Spring 梳理-JdbcTemplate简介

    JdbcTemplate简介 Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中. JdbcTempla ...

  8. Actor 模型中的通信模式

    在 Actor 模型中所有的 Actor 之间有且只有一种通信模式,那就是 tell 的方式,也就是 fire and forget 的方式.但是在实际的开发过程中工程师们逐渐总结出了一些常用的通信模 ...

  9. .Net Core 商城微服务项目系列(十二):使用k8s部署商城服务

    一.简介 本篇我们将会把商城的服务部署到k8s中,同时变化的还有以下两个地方: 1.不再使用Consul做服务的注册和发现,转而使用k8s-dns来实现. 2.不再使用Ocelot作为业务网关,使用T ...

  10. 基于vue-cli、elementUI的Vue超简单入门小例子

    - 这个例子还是比较简单的,独立完成后,能大概知道vue是干嘛的,可以写个todoList的小例子. - 开始写例子之前,先对环境的部署做点简单的介绍,其实和Vue官方的差不多. #如若没有安装过vu ...