线程的概念

现在的操作系统几乎都支持运行多个任务,而在操作系统内部,一个任务往往代表的执行的某一个程序,也就是运行中的程序,运行的程序是一个动态的概念,也就是所说的进程,而在进程内部,往往有许多顺序执行流,这些顺序执行流就是线程。

线程的创建

Python提供了 _thread 和 threading 两个模块来支持多线程,其中 _thread 提供低级别的、原始的线程支持,以及一个简单的锁,正如它的名字所暗示的,一般编程不建议使用 thread 模块;而 threading 模块则提供了功能丰富的多线程支持。

Python 主要通过两种方式来创建线程:

  1. 使用 threading 模块的 Thread 类的构造器创建线程。
  2. 继承 threading 模块的 Thread 类创建线程类。

使用Thread类创建线程

Thread类的构造或者说初始化的__init__方法如下:

__init__(self, group=None, target=None, name=None, args=(), kwargs=None, *,daemon=None)

上面的构造器涉及如下几个参数:

  • group:指定该线程所属的线程组。目前该参数还未实现,因此它只能设为 None。
  • target:指定该线程要调度的目标方法。
  • args:指定一个元组,以位置参数的形式为 target 指定的函数传入参数。元组的第一个元素传给 target 函数的第一个参数,元组的第二个元素传给 target 函数的第二个参数……依此类推。
  • kwargs:指定一个字典,以关键字参数的形式为 target 指定的函数传入参数。
  • daemon:指定所构建的线程是否为后代线程。

通过 Thread 类的构造器创建井启动多线程的步骤如下:

  1. 调用 Thread 类的构造器创建线程对象。在创建线程对象时,target 参数指定的函数将作为线程执行体。
  2. 调用线程对象的 start() 方法启动该线程。

示例:

import  threading

#定义一个函数,该函数返回当前执行的进程名字
def fc(value):
for i in range(value):
    # 调用threading模块current_thread()函数获取当前线程
    # 线程对象的getName()方法获取当前线程的名字
print(threading.current_thread().getName() + "--->" + str(i)) #定义线程执行体
for i in range():
print(threading.current_thread().getName() + '--->' + str(i))
if i == : #当if条件成立时,执行子线程
sd = threading.Thread(target=fc, args=(, ))
sd.start()
print("主线程执行完毕")

程序可以通过 setName(name) 方法为线程设置名字,也可以通过 geName() 方法返回指定线程的名字,这两个方法可通过 name 属性来代替。在默认情况下,主线程的名字为 MainThread,用户启动的多个线程的名字依次为 Thread-1、Thread-2、Thread-3、...、Thread-n 等。

继承 threading 模块的 Thread 类创建线程类

通过继承 Thread 类来创建并启动线程的步骤如下:

  1. 定义 Thread 类的子类,并重写该类的 run() 方法。run() 方法的方法体就代表了线程需要完成的任务,因此把 run() 方法称为线程执行体。
  2. 创建 Thread 子类的实例,即创建线程对象。
  3. 调用线程对象的 start() 方法来启动线程。

示例:

import  threading

class DefineThread(threading.Thread):

    def __init__(self):
#调用父类的初始化方法。
threading.Thread.__init__(self) #或者
#super().__init__()
self.i =
#重新定义run方法,也就是线程的执行体
def run(self):
while self.i < :
print(threading.current_thread().name + "--->" + str(self.i))
self.i += #主程序
for i in range():
print(threading.current_thread().name + '--->' + str(i))
if i == :
dt = DefineThread()
dt.start() print("主线程执行完毕")

方法

join方法

Thread 提供了让一个线程等待另一个线程完成的 join() 方法。当调用程序调用另外一个线程的join()方法时,需要等待另外一个线程执行完成才继续执行当前的程序。也就是说当前的执行程序会被阻塞。

示例:

import  threading

def ft(value):
for i in range(value):
print(threading.current_thread().name + "--->" +str(i)) #主程序
for i in range():
if i == :
dt = threading.Thread(target=ft, args=(, ), name = "被其他线程调用join()方法的线程")
dt.start()
dt.join()
print(threading.current_thread().name + "--->" + str(i)) print("主线程执行完毕")

输出如下:

MainThread--->
MainThread--->
被其他线程调用join()方法的线程--->
被其他线程调用join()方法的线程--->
被其他线程调用join()方法的线程--->
被其他线程调用join()方法的线程--->
被其他线程调用join()方法的线程--->
MainThread--->
MainThread--->
MainThread--->
主线程执行完毕

可以看出,当子线程在执行的时候,主线程是被阻塞的。

daemon(守护或者后台进程)

daemon属性用来设置线程运行在后台,默认是运行在前台。当所有的前台进程都死掉时,后台进程也结束,不管后台进程是否运行完毕。

示例

import  threading

def ft(value):
for i in range(value):
print(threading.current_thread().name + "--->" +str(i)) t = threading.Thread(target=ft, args=(, ), name = "后台线程", daemon=True)
t.start()
#如果没有在创建线程对象指定daemon=True,那么也可以通过下面的属性设置
#t = threading.Thread(target=ft, args=(, ), name = "后台线程")
#t.daemon = True #主程序
for i in range():
print(threading.current_thread().name + "--->" + str(i)) print("主线程执行完毕")

上述程序在执行的时候,正常应该是t这个线程对象执行到99的时候才推出,但是,在主程序内部的线程执行完毕(也就是前台进程完毕),那么后台进程也会随之退出。

从上面的程序可以看出,主线程默认是前台线程,t线程默认也是前台线程。但并不是所有的线程默认都是前台线程,有些线程默认就是后台线程。前台线程创建的子线程默认是前台线程,后台线程创建的子线程默认是后台线程。

可见,创建后台线程有两种方式:

  1. 主动将线程的 daemon 属性设置为 True。
  2. 后台线程启动的线程默认是后台线程。

注意,当前台线程死亡后,Python 解释器会通知后台线程死亡,但是从它接收指令到做出响应需要一定的时间。如果要将某个线程设置为后台线程,则必须在该线程启动之前进行设置。也就是说,将 daemon 属性设为 True,必须在 start() 方法调用之前进行,否则会引发 RuntimeError 异常。

python3之线程(一)的更多相关文章

  1. python3之线程与进程

    1.CPU运行原理 我们都知道CPU的根本任务就是执行指令,对计算机来说最终都是一串由“0”和“1”组成的序列.CPU从逻辑上可以划分成3个模块,分别是控制单元.运算单元和存储单元,这三部分由CPU内 ...

  2. Python3 进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  3. Python3使用线程

    Python2标准库中提供了两个模块thread和threading支持多线程.thread有一些缺陷在Python3中弃用,为了兼容性,python3 将 thread 重命名为 "_th ...

  4. python3线程启动与停止

    转自: https://blog.csdn.net/weixin_38125866/article/details/76795462 https://www.cnblogs.com/lcchuguo/ ...

  5. 洗礼灵魂,修炼python(87)-- 知识拾遗篇 —— 线程(1)

    线程(上) 1.线程含义:一段指令集,也就是一个执行某个程序的代码.不管你执行的是什么,代码量少与多,都会重新翻译为一段指令集.可以理解为轻量级进程 比如,ipconfig,或者, python   ...

  6. python3之协程

    1.协程的概念 协程,又称微线程,纤程.英文名Coroutine. 线程是系统级别的它们由操作系统调度,而协程则是程序级别的由程序根据需要自己调度.在一个线程中会有很多函数,我们把这些函数称为子程序, ...

  7. Python 3 线程模型,进程模型记录

    最近需要使用 python3 多线程处理大型数据,顺道探究了一下,python3 的线程模型的情况,下面进行简要记录: 多线程运行的优点: 使用线程可以把程序中占用时间较长的任务放到后台去处理: 用户 ...

  8. Python之路PythonThread,第四篇,进程4

    python3  进程/线程4 进程间同步互斥方法: from multiprocessing import Lock 创建 进程锁对象 lock = Lock() lock.acquire()  给 ...

  9. Python3 与 C# 并发编程之~ 线程篇

      2.线程篇¶ 在线预览:https://github.lesschina.com/python/base/concurrency/3.并发编程-线程篇.html 示例代码:https://gith ...

随机推荐

  1. 分享-SpringCloud微服务架构图

    1: 为大家分享一张SpringCloud微服务通用架构图 ​标题 此图仅供参考: 需要原图的同学请移步 >>>>>>>>> 这里 如有不合理的地 ...

  2. Linux REDHAT 7 关闭、禁用防火墙服务

    1 查看防火墙状态 [root@lvxinghao ~]# systemctl status firewalld 2 查看开机是否启动防火墙服务[root@lvxinghao ~]# systemct ...

  3. [AIR] NativeExtension在IOS下的开发实例 --- ANE文件的打包(三)

    来源:http://bbs.9ria.com/thread-102041-1-1.html 好了,前面的准备工作做的差不多了.此时我们应用有下面几个文件:extension.xml    CoolEx ...

  4. NSLog的各种打印格式符和打印CGRect相关结构体

    1.打印CG开头的数据类型,如CGRect,CGSize等方法 1.1 打印CGRect : NSLog(@"%@", NSStringFromCGRect(someCGRect) ...

  5. xadmin安装

    1 安装满足django2的版本 pip3 install https://codeload.github.com/sshwsfc/xadmin/zip/django2 2 urls.py里面增加路由 ...

  6. Python学习日记(五) 编码基础

    初始编码 ASCII最开始为7位,一共128字符.最后确定8位,一共256个字符,最左边的为拓展位,为以后的开发做准备. ASCII码的最左边的一位为0. 基本换算:8位(bit) = 1字节(byt ...

  7. 关于SpringBoot下template文件夹下html页面访问的一些问题

    springboot整合了springmvc的拦截功能.拦截了所有的请求.默认放行的资源是:resources/static/ 目录下所有静态资源.(不走controller控制器就能直接访问到资源) ...

  8. kali linux 虚拟机克隆之后版本回退问题

    今天在做虚拟机的克隆的之后发现 之前kali linux 系统内核升级后的更改全部又回退到之前的版本,也就是说之前安装的软件被删除了,现在需要自己重新安装一遍  ,(我滴个乖乖哟) 这里就不放图了.

  9. [nginx] nginx源码分析--SNI性能分析

    概念 我们已经知道什么是SNI,以及如何为用户配置SNI. [nginx] nginx使用SNI功能的方法 问题 通过观察配置文件,可以发现,针对每一个SSL/TLS链接, nginx都会动态的查找( ...

  10. [ike][ipsec] child sa rekey机制的细节分析

    子标题:ipsec rekey是否会导致丢包 author: classic_tong 前言 什么叫rekey. rekey是指ipsec的通信两端定期更换加密信道秘钥的机制. 为了安全性考虑,随着秘 ...