前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python的线程Thread的自我介绍

Python的线程Thread的自我介绍

作者头像
我被狗咬了
发布2019-09-25 20:15:41
6620
发布2019-09-25 20:15:41
举报
文章被收录于专栏:Python乱炖

Hello,我是Python里面的线程,今天我就来向大家做个自我介绍吧!

首先,我想说的是,我(线程)不只是在python中会出现,我在任何编程语言中都可以使用代码将我实现,所以,简单来说我是一个机制,在一些特别的情况下会遇到我。

在我自我介绍之前,我先要介绍我的组织——进程( 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.

进程呢,是容纳我的地方,一个进程可以容纳包含许多许多的线程

关于组织(进程)和我(线程)之间的关系如下:

A 在实现了线程的操作系统中,线程是操作系统能够运算调度的最小单位.

(我是最小单位,组织里面有多个我,我是不能被拆分的)

B 线程被包含在进程中,是进程的实际运作单位.

(我隶属于组织,组织是以一个我为单位,由好多很多个我组成的)

C 一个程序的执行实例就是一个进程.

(关于组织其实很好理解,一个组织就是一个完整程序)

介绍完我和进程的关系后,现在我开始来自我介绍啦!

首先要和大家介绍一下我的四个形态:

Ready:就是一开始在准备的状态,一旦我运行了,就在等着被组织调度呢。

Running:这个状态下,我正在被组织派出去执行任务呢。

Blocked:这个时候我就很难受了,由于接收到组织的指令,让我停止当前任务,处于待命状态,进又不是,退又不是,不能动,很难受啊。

Terminated:终结状态,此时的我回到组织休息了,无论我的任务是完成了还是被取消了,我都回到组织准备休假了。

搞清楚这些之后我们就来看看在python中的我是什么样子吧!

在python中,我的名字就是:threading模块

如果想使用我,就需要:

import threading

或者直接引入模块中的方法:

from threading import thread

我们先来看看开发者是怎么定义我的吧:

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

在构造函数中,我包含以下几个参数:

* target: 线程调用的对象,就是目标函数.(必须要写)

* name: 为线程起个名字.(必须要写)

* args: 为目标函数传递实参, 元组.(有需要传入线程参数的时候才会用)

* kwargs: 为目标函数关键字传参, 字典.(同上,只不过是字典类型的)

运行结果:

通过threading.Thread创建一个线程对象,target是目标函数,name可以指定名称.

但是,仅仅生成线程对象是不行的,我们还需要启动它,这个时候就需要调用start方法,如上图第七行代码所示。

线程会执行函数(def function():.....),是因为线程中就是执行代码的,而最简单的封装就是函数,所以还是函数调用.函数执行完,线程也会随之退出.下面我们看一个一直执行的例子:

我们把刚刚的运行函数变成了一个死循环,所以他会一直不停的运行下去。

结果:

刚刚在运行第一个例子的时候我们看到了,当run_thread函数运行结束的时候,我们的线程也结束了,所以说,线程结束的标准就是,当它需要执行的东西执行完毕了,它就自然而然的结束了,但是也有例外,如果说,线程执行的函数抛出了异常呢,线程还会继续执行下去吗?

我们来看看例子:

还是将上面的run_thread函数修改一下:

看一下运行结果:

ok,看了上面的运行结果我们就知道答案是否定的,一旦线程内的方法抛出异常,那么它本身将不会再执行了。所以我们总结一下,一般线程在什么时候会退出:

  • 线程函数内语句执行完毕.
  • 线程函数中抛出未处理的异常.

在python中,线程不具有优先级或线程组的概念,也不能被销毁、停止、挂起,自然也没有恢复、中断。这一点和其他语言是不一样的。

下面我们讲一下线程的属性和方法:

current_thread() # 返回当前线程对象.

main_thread() # 返回主线程对象.

active_count() # 当前处于alive状态的线程个数.

enumerate() # 返回所有活着的线程的列表

get_ident() # 返回当前线程ID,非0整数.

start() # 启动线程。每一个线程必须且只能执行该方法一次。

run() # 运行线程函数。

写个代码看看他们是什么吧:

执行结果:

我们现在来看一下run方法是什么方法,怎么现在都没用过?

其实我们已经在用了,我们之前用的start()方法会调用run()方法,run()方法可以运行函数。

我们写一个自己的类继承自threading,我们重写了start方法和run方法,并且在里面加了标记,现在我们来跑一下代码:

结果打印出来了”调用了run方法“,这就证明了我们刚刚的说法是对的

下面我们看看多线程,多线程是什么呢?当然就是许多许多线程同时在一起工作啦!

很简单,我们可以给刚刚的函数生成多个线程对象不久可以了吗?(是不是很聪明,哈哈哈哈)

看输出结果:

正好是执行四次(他们的顺序是无序的,我把t1-t4这样写出来是为了证明有四个线程,他们之间运行没有先后,就看谁先抢到资源,谁就先运行了)

当使用start方法启动线程后,进程内有多个活动的线程并行的工作,就是多线程。

一个进程中至少有一个线程,并作为程序的入口,这个线程就是主线程。一个进程至少有一个主线程。其他线程称为工作线程。

在多线程的时候我们经常会用到join方法,join方法是控制一个线程调用另一个线程的方法。join方法有一点是要强调的,就是它是保证当前线程运行完成后再去执行其他线程的。

我们来看一个简单的例子:

首先我们不用join:

它会直接把结果一下子就输出来,程序结束,不会一秒一秒的等。

如果我们把join加上,hello world!就会一秒一秒地有序输出,然后结束程序。

join有一个timeout参数:

  1. 当设置守护线程时,含义是主线程对于子线程等待timeout的时间将会杀死该子线程,最后退出程序。所以说,如果有10个子线程,全部的等待时间就是每个timeout的累加和。简单的来说,就是给每个子线程一个timeout的时间,让他去执行,时间一到,不管任务有没有完成,直接杀死。
  2. 没有设置守护线程时,主线程将会等待timeout的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。

关于线程,我们今天就介绍到这里啦!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python乱炖 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档