python自我介绍_Python的线程Thread的自我介绍

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: 为目标函数关键字传参, 字典.(同上,只不过是字典类型的)

c62f9589a45498187cd424fd66a100c1.png

运行结果:

11df7847aad994d79350d8fc03b29682.png

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

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

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

98868f1b98de766d43160c87f8ebfaa4.png

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

结果:

50dc0f1afbc071fc41f4c75b9969e398.png

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

我们来看看例子:

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

b657137d50fb5e88202217ad71bdc10f.png

看一下运行结果:

6ecf27b90cd6dfb67a21933f653d5d75.png

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

线程函数内语句执行完毕.

线程函数中抛出未处理的异常.

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

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

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

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

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

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

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

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

run()  # 运行线程函数。

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

668dd406834e455e0dee8cddd8d0c72a.png

执行结果:

1cc52f896e312b7ea1a4bbc1fb7cd038.png

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

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

9c2aa829b839413e6345ea7f91f39b6b.png

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

3b7b4203f251309f446bf5f1846638e5.png

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

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

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

3f8a849b16ba919eac292f09e822bc47.png

看输出结果:

40f0a3123cc8d6e22b0dc3ffe0825f84.png

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

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

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

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

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

首先我们不用join:

4d6832eae442e1baed1e2478682a197c.png

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

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

join有一个timeout参数:

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

没有设置守护线程时,主线程将会等待timeout的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。

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

听说有气质的人都会关注这个公众号!

7745d67ae3769227b0031d5e6eb1581d.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值