Python菜鸟教程:如何创建线程

2022-08-0521:04:14编程语言入门到精通Comments1,081 views字数 2436阅读模式

学习线程的创建之前,我们先来了解一下线程对象和线程体这两个概念,线程对象就是我们通过线程模块中的线程类创建的对象,而线程体就是线程执行的相关内容,例如指令和函数等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

线程有四个变化状态:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

1) 创建线程文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

当创建一个新的进程时,也创建一个新的线程,进程中的线程可以在同一进程中创建新的线程。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

2) 终止线程文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

可以正常终止自己,也可能某个线程执行错误,由其它线程强行终止。终止线程操作主要负责释放线程占有的寄存器和栈。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

3) 阻塞线程文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

当线程等待某个事件无法运行时,停止其运行。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

4) 唤醒线程文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

当阻塞线程的事件发生时,将被阻塞的线程状态置为就绪态,将其挂到就绪队列,进程仍然具有与执行相关的状态。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

Python中有两个系统模块供我们使用:_thread和threading,前者为低级模块,后者对前者进行了封装,通常我们会使用threading模块。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

1. threading模块文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

threading是一种面向对象的模块,其中使用最多的是Thread类,还有几种比较常用的函数:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

threading.active_count():返回当前活动的线程数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

threading.current_thread():返回当前的Thread对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

threading.main_thread():返回主线程对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

 2. Thread类文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

我们可以使用Thread类来代表一个线程对象,它的语法格式如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

1
Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

group应该为None,在实现ThreadGroup类时为将来的扩展保留。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

target是run()方法要调用的可调用对象。默认为“无”,表示不调用任何内容。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

name是线程名。默认情况下,一个唯一的名称由“Thread-N”构成,其中N是一个小的十进制数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

args是目标调用的参数元组。默认为()。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

kwargs是目标调用的关键字参数字典。默认为{}。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

我们通过一个例子来看一下,代码如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import threading
import time
def test():
    for in range(2):
        time.sleep(1)#设置一个等待时间
        print('这是第%s线程'%threading.current_thread().name)
if __name__ == '__main__':
    my_list = []
    for in range(5):
        = threading.Thread(target=test)
        my_list.append(a)
    for in my_list:
        j.start()
    for in my_list:
        m.join()

运行结果为:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

1
2
3
4
5
6
7
这是第Thread-2线程
这是第Thread-1线程
这是第Thread-5线程这是第Thread-4线程
这是第Thread-3线程
这是第Thread-1线程
这是第Thread-2线程
这是第Thread-5线程这是第Thread-4线程这是第Thread-3线程

通过运行结果我们可以看出,线程的执行顺序是不确定的,再加上等待时间,就会出现等待的空白片段,关于这个我们在操作系统中有很多相关内容。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

我们主要是通过threading.Thread(target=test)来创建线程,然后把四个线程放在一个列表中,然后我们再通过start()方法开启线程,join()方法等待线程结束。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

3. 通过Thread子类创建线程文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

我们还可以定义一个子类,使这个子类继承Thread线程类中的方法来创建线程,代码如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import threading
import time
class MyThread(threading.Thread):
    def __init__(self,name = None):
        super().__init__(name = name)
    def run(self):
        = threading.current_thread()
        for in range(4):
            print('第%d次执行线程%s'%(i,t.name))
            time.sleep(1)
        print('执行完毕')
if __name__ == '__main__':
    thread_one = MyThread()
    thread_one.start()
    thread_one.join()
    thread_two = MyThread()
    thread_two.start()

运行结果如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

1
2
3
4
5
6
7
8
9
10
0次执行线程Thread-10次执行线程Thread-1
1次执行线程Thread-1
2次执行线程Thread-1
3次执行线程Thread-1
执行完毕
0次执行线程Thread-2
1次执行线程Thread-2
2次执行线程Thread-2
3次执行线程Thread-2
执行完毕

这种方式等于先定义了一个子类,然后继承了threading.Thread的线程类,然后定义run()方法,然后在主程序中使用我们定义的子类创建两个线程,这两个线程会自动调用run()方法,我们把线程启动然后等待即可。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

4. 总结文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

上面所讲的是我们创建线程的时候最常用的两种方式,通常我们会选择后者去进行创建,在编程的时候给每个线程执行的时间time.sleep(),这样会通过线程暂停而给其它线程来争抢执行的机会,这一点我们在后面会学习到。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/26599.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ymba/26599.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定