python threading-单线程 多线程 主线程 子线程 setDeamon join

  • 单线程
  • 多线程
    • 主线程和子线程
    • setDaemon()
    • join()
    • 测试多线程下程序运行的时间
    • 创建多个线程
    • 优化子线程

单线程

用单线程 ,做听音乐和看电影两件事儿,首先排一下顺序。

import timedef music():for i in range(2):print("I was listening to music. %s" %time.ctime())time.sleep(1)def move():for i in range(2):print("I was at the movies. %s" %time.ctime())time.sleep(5)if __name__=='__main__':music()move()print("all over %s" %time.ctime())

输出结果:

I was listening to music. Wed Oct 20 15:42:19 2021
I was listening to music. Wed Oct 20 15:42:20 2021
I was at the movies. Wed Oct 20 15:42:21 2021
I was at the movies. Wed Oct 20 15:42:26 2021
all over Wed Oct 20 15:42:31 2021

time.sleep(1)是延时1s的意思。我们先听了一首音乐,通过for循环来控制音乐的播放了两次,每首音乐播放需要1秒钟,sleep()来控制音乐播放的时长。接着我们又看了一场电影,每一场电影需要5秒钟,通过for循环看两遍。在整个结束后,输出当前的时间。

可以发现:整个代码只能是先干一件事再干一件事。

用时:开始42分19结束是42分31,总耗时为12s。

多线程

cpu同时干多个活都没问题的,不需要让一件事一直占着cpu不放;于是,操作系统就进入了多任务时代。

python提供了threading模块来实现多线程。可以 引入threadring来同时播放音乐和视频。

import threading
import timedef music():for i in range(2):print("I was listening to music. %s" %time.ctime())time.sleep(1)def move():for i in range(2):print("I was at the movies. %s" %time.ctime())time.sleep(5)
'''
创建了threads数组,创建线程t1,使用threading.Thread()方法,在这个方法中调用music方法target=music,把创建好的线程t1装到threads数组中。接着以同样的方式创建线程t2,并把t2也装到threads数组。
'''
threads = []
t1 = threading.Thread(target=music)
threads.append(t1)
t2 = threading.Thread(target=move)
threads.append(t2)if __name__=='__main__':for t in threads:t.setDaemon(True)t.start()print("all over %s" %time.ctime())

主线程和子线程

主线程:是执行主(main)方法的线程.

子线程:被Thread包含的“方法体”或者“委托”均为子线程

setDaemon()

当启动一个线程时设置thread.setDaemon(True),则该线程为守护线程(也可以称为后台线程)。表示该线程是不重要的,进程退出时不需要等待这个线程执行完成。这样做的意义在于:避免子线程无限死循环,导致退不出程序,也就是避免了孤儿进程的出现。

当不设置或者thread.setDaemon(False)时,主进程执行结束时,会等待线程结束。

上述程序如果设置t.setDaemon(False),那么将输出:

I was listening to music. Wed Oct 20 16:11:27 2021
I was at the movies. Wed Oct 20 16:11:27 2021
all over Wed Oct 20 16:11:27 2021
I was listening to music. Wed Oct 20 16:11:28 2021
I was at the movies. Wed Oct 20 16:11:32 2021

可以看到,在主线程进行完之后,也就是输出all over Wed Oct 20 16:11:27 2021之后,还会继续执行没完成的子线程。

如果设置setDaemon(True),那么将输出:

I was listening to music. Wed Oct 20 16:03:27 2021
I was at the movies. Wed Oct 20 16:03:27 2021
all over Wed Oct 20 16:03:27 2021

也就是说,子线程启动后,父线程也继续执行下去,当父线程执行完最后一条语句print(“all over %s” %time.ctime())后,没有等待子线程,直接就退出了,同时子线程也一同结束。

join()

import threading
import timedef music():for i in range(2):print("I was listening to music. %s" %time.ctime())time.sleep(1)def move():for i in range(2):print("I was at the movies. %s" %time.ctime())time.sleep(5)threads = []
t1 = threading.Thread(target=music)
threads.append(t1)
t2 = threading.Thread(target=move)
threads.append(t2)if __name__=='__main__':for t in threads:t.setDaemon(True)t.start()for t in threads:t.join()print("all over %s" %time.ctime())

运行结果:

I was listening to music. Wed Oct 20 16:21:41 2021
I was at the movies. Wed Oct 20 16:21:41 2021
I was listening to music. Wed Oct 20 16:21:42 2021
I was at the movies. Wed Oct 20 16:21:46 2021
all over Wed Oct 20 16:21:51 2021

我们只对上面的程序加了个join()方法,用于等待线程终止。join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。

也就是说,必须等待for循环里的两个进程都结束后,才去执行主进程。

从执行结果可看到,music 和move 是同时启动的。

开始时间21分41秒,结束时间为21分51秒,总耗时为10秒。比单线程用时减少了2秒。

测试多线程下程序运行的时间

现在把music的sleep()的时间调整为5秒。

import threading
import timedef music():for i in range(2):print("I was listening to music. %s" %time.ctime())time.sleep(5)def move():for i in range(2):print("I was at the movies. %s" %time.ctime())time.sleep(5)threads = []
t1 = threading.Thread(target=music)
threads.append(t1)
t2 = threading.Thread(target=move)
threads.append(t2)if __name__=='__main__':for t in threads:t.setDaemon(True)t.start()for t in threads:t.join()print("all over %s" %time.ctime())
I was listening to music. Wed Oct 20 16:41:59 2021
I was at the movies. Wed Oct 20 16:41:59 2021
I was listening to music. Wed Oct 20 16:42:04 2021
I was at the movies. Wed Oct 20 16:42:04 2021
all over Wed Oct 20 16:42:09 2021

可以看到,最后还是用时10s。

如果是用单线程的话,用时将达到5*4=20s。

创建多个线程

从上面例子中发现线程的创建是颇为麻烦的,每创建一个线程都需要创建一个tx(t1、t2、…),如果创建的线程多时候这样极其不方便。下面对通过例子进行继续改进:

import threading
import timedef music(func):for i in range(2):print("Start music: %s! %s" % (func, time.ctime()))time.sleep(5)def move(func):for i in range(2):print("Start playing: %s! %s" % (func, time.ctime()))time.sleep(5)'''
创建了一个player()函数,这个函数用于判断播放文件的类型。如果是mp3格式的,我们将调用music()函数,如果是mp4格式的我们调用move()函数。哪果两种格式都不是那么只能告诉用户你所提供有文件我播放不了
'''def player(name):r = name.split('.')[1]if r == 'mp3':music(name)else:if r == 'mp4':move(name)else:print("ERROR:The format is not recognized!")'''
创建了一个list的文件列表,注意为文件加上后缀名。然后我们用len(list) 来计算list列表有多少个文件,这是为了帮助我们确定循环次数。
'''list = ['jjj.mp3', 'yyy.mp4']threads = []files = range(len(list))'''
通过一个for循环,把list中的文件添加到线程中数组threads[]中。
'''for i in files:t = threading.Thread(target=player, args=(list[i],))threads.append(t)'''
启动threads[]线程组,最后打印结束时间。
'''
if __name__ == '__main__':for i in files:threads[i].start()for t in files:threads[i].join()print("all over %s" %time.ctime())

运行结果:

Start music: jjj.mp3! Wed Oct 20 17:04:49 2021
Start playing: yyy.mp4! Wed Oct 20 17:04:49 2021
Start playing: yyy.mp4! Wed Oct 20 17:04:54 2021
Start music: jjj.mp3! Wed Oct 20 17:04:54 2021
all over Wed Oct 20 17:04:59 2021

其中,split()可以将一个字符串拆分成两部分,然后取其中的一部分。也就是说,判断list[i]里面后缀是mp3还是mp4类型的。

>>> x = 'testing.py'
>>> s = x.split('.')[1]
>>> if s=='py':print(s)py

现在向list数组中添加一个文件,程序运行时会自动为其创建一个线程。

优化子线程

我们发现player()用于判断文件扩展名,然后调用music()和move() ,其实,music()和move()工作是类似的,可以改进一下,不管什么文件都可以播放。

import threading
import time'''
创建player()函数,用于接收file和t,用于确定要播放的文件及时长。
'''
def player(file, t):for i in range(2):print("Start playing: %s! %s" % (file, time.ctime()))time.sleep(t)'''
字典list ,用于定义要播放的文件及时长(秒),通过字典的items()方法来循环的取file和t,取到的这两个值用于创建线程。
'''list = {'jjj.mp3': 3, 'yyy.mp4': 5, 'mmm.mp3': 4}threads = []files = range(len(list))for file, t in list.items():tx = threading.Thread(target=player, args=(file, t))threads.append(tx)if __name__ == '__main__':for i in files:threads[i].start()for t in files:threads[i].join()print("all over %s" %time.ctime())

运行结果:

Start playing: jjj.mp3! Wed Oct 20 17:50:43 2021
Start playing: yyy.mp4! Wed Oct 20 17:50:43 2021
Start playing: mmm.mp3! Wed Oct 20 17:50:43 2021
Start playing: jjj.mp3! Wed Oct 20 17:50:46 2021
Start playing: mmm.mp3! Wed Oct 20 17:50:47 2021
Start playing: yyy.mp4! Wed Oct 20 17:50:48 2021
all over Wed Oct 20 17:50:51 2021

python threading-单线程 多线程 主线程 子线程 setDeamon join相关推荐

  1. 【EventBus】事件通信框架 ( 发送事件 | 判断发布线程是否是主线程 | 子线程切换主线程 | 主线程切换子线程 )

    文章目录 前言 一.根据不同的线程模式进行不同的线程切换操作 二.完整代码示例 前言 发布线程发布事件之后 , 消息中心需要转发这些事件 , 并执行相应的订阅方法 ; 在转发的过程中 , 需要针对订阅 ...

  2. QT 主线程子线程互相传值

    本文实现了主线程给子线程传值.子线程给主线程传值.主线程子线程的互相传值.线程源文件mythread.h..cpp:主线程文件mainwindow.h..cpp;下面程序先从主线程调用子线程,子线程给 ...

  3. 多线程经典问题1——主线程子线程交替问题

    提出问题: * 子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次.如此循环50次. 分析:这个实际上是非常easy的问题.即子线程r ...

  4. 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

    文章目录 一.判定当前线程是否是主线程 二.子线程中执行主线程方法 三.主线程中执行子线程方法 一.判定当前线程是否是主线程 在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如 ...

  5. Android ThreadUtil 线程公共类,判断是否在主线程/ 子线程执行 相关操作

    前言:通常,我们写的公共的模块给别人用,但是这个模块又必须在特定的线程中执行. 比如,一个加载网络图片的的方法,需要在子线程中执行. /** * 加载网络图片 */ private void load ...

  6. Android 主线程子线程执行关系

    Android 切换线程的方式[我常用的]     1. Handler.post[切换至主线程]     2. new Thread().start()[切换至子线程] 3. 线程池 ThreadP ...

  7. linux_主线程子线程退出关系

    我们在一个线程中经常会创建另外的新线程,如果主线程退出,会不会影响它所创建的新线程呢?下面就来讨论一下. 1. 主线程等待新线程先结束退出,主线程后退出.正常执行. 实例代码: #include &q ...

  8. 主线程 子线程死掉_当线程死时,子进程也会死

    我有一个程序可以触发Python计时器来生成子进程.一旦程序终止或终止,这些子进程就应该终止.为了做到这一点,我使用了"prctl hack",它设置了一旦父对象死亡,子对象应该接 ...

  9. Python threading Thread多线程的使用方法

    Python threading Thread多线程的使用方法 参考资料:<Python 多线程>http://www.runoob.com/python/python-multithre ...

最新文章

  1. Toast 位置的改变 和 Toast的简单用法
  2. python 利用正则构建一个计算器
  3. 新的一年,努力努力!
  4. 第一章--最小的“操作系统”
  5. 《关于我的那些面经》滴滴Java岗(附答案)
  6. 使用软链接的方式迁移Docker
  7. 互联网日报 | 6月15日 星期二 | 凯撒旅业拟换股吸并众信旅游;爱回收预计6月18日登陆纽交所;顺丰航空机队规模增至66架...
  8. 利用mongodb开发lbs应用实践【转】
  9. 【原创】《算法导论》链表一章带星习题试解——附C语言实现
  10. sql中如何将视图中某一字段相同的数据合并 不同内容的字段相加_Tableau基础如何合并你的数据?理解与逻辑(上)...
  11. 计算机上图片打不开,电脑上打不开jpg格式的图片是怎么回事?
  12. 百度之星2017 HDU 6114 Chess 组合数学
  13. 宋登高 php,HDwiki百科建站第一期
  14. 【机器学习】谱聚类(Spectral Clustering)
  15. RLS算法到卡尔曼滤波 II
  16. 数据库外键的作用,以及和主键的区别
  17. android 微信公众号开发教程,微信公众号-开发者-自定义菜单,公众开发者
  18. 干货!教你4种文件恢复方法,再也不怕误删除!
  19. 你在SOA实现中应用筒仓分析了吗?
  20. excel打开多个表格文件显示在一个窗口/表格怎么办?excel缩放一个文件,另一个文件也缩放怎么办?excel打开多个文件重叠怎么办?Excel2010文档在同一个窗口中显示问题如何解决

热门文章

  1. MS SQL查询库、表、列数据结构信息汇总
  2. SQLite CodeFirst、Migration 的趟坑过程 [附源码]
  3. Linux kubuntu x64系统下解决QT5.12编辑菜单和工具栏不显示图标问题
  4. CentOS7 搭建Pulsar 消息队列环境,CentOS(Linux)部署Pulsar,亲测成功,以及Python操作Pulsar实例驱动
  5. JQuery Datatables辅助函数
  6. 春晓JAVA的横排和竖排输出
  7. 可汗学院 统计学(12到34集)
  8. 红帽linux5.5序列号,Redhat 5 安装序列号及版本说明
  9. java白色_java-将精灵颜色更改为白色
  10. 线程中如何使用对象_在 Flink 算子中使用多线程如何保证不丢数据?