栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

python多线程threading详解(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python多线程threading详解(一)

1.简单了解下:

线程,是操作系统能够进行运算调度的最小单位。它被包含在进程之中,一个进程可以运行多个线程,线程是进程中的实际运作单位,一条线程指的是进程中的一个单一顺序的控制流。但是,python中的多线程,由于GIL(全局解释器锁)的存在,并不是真正的并行,工作模式是线程间不断的、快速的切换来完成任务,同一时间只能有一个线程工作。

2.进程和线程的关系,举个例子说明:

一个进程就像一台车,它是一个容器,有不同的功能,车本身并没有主动地做任何的事情,而线程可以理解成使用车的人,他可以踩油门,可以踩刹车,可以打方向盘,看到这里,有人可能会说,我可以一边踩油门一边打方向盘啊,同时进行,可是在python是,存在GIL,你只能在同一时间干一件事。

所以只能在IO密集型的任务中使用多线程才有意义,比如,你打一个文件,需要2秒,你有2个文件需要打开,如果不使用多线程,你打开这2个文件,一共需要4秒,使用多线程,只需要2秒。过程如下:

线程1获取GIL的使用权,打开文件1,因为需要等待2秒,所以在等待的时候,交出了GIL的使用权;线程2,获得使用权,打开文件2,等待2秒,因为在这个切换中非常快,感受不到这种切换,觉得是同时打开了2个文件,共耗时2秒。

实现多线程的方式有2种,一种是使用调用threading模块的Thread, 一种是通过构建多线程类(继承Thread)来实现。

方法一,调用Thread来实现多线程。

1.demo 1

import time
from threading import Thread, current_thread


def demo():
    print(f'子线程开始, 线程名字: {current_thread().name}')
    time.sleep(2)  # 模拟等待操作, 模拟耗时的io任务
    # current_thread函数, 返回当前线程对象, 调用name方法输出当前线程名
    print(f'子线程结束, 线程名字: {current_thread().name}')


if __name__ == '__main__':
    print('主线程开始...')
    threads = [Thread(target=demo) for _ in range(3)]  # 这里是创建4个线程,放到一个列表里
    for t in threads:
        t.start()  # 启动线程
    for t in threads:
        t.join()  # 线程等待
    print('主线程结束...')

输出如下:

这里解释下, t.start()是启动线的方法, t.join()是线程等待的意思(阻塞调用这个方法的线程(主线程是调用子线程的方法)),在这里用t.join(),主线程会等所有的子线程完成后再结束,因为每一个子线程都启用了t.join();

疑问一:t.join()可以跟t.start()放在同一循环内吗?

答案是不可以,如果放在一个循环里,每启动一个子线程t.start后,就马上做t.join,这个时候,启动的这个子线程是强占资源的,抢到这个资源后,必须要等启动的这个子线程完成后,才能启动下一个子线程,

也就是说,这个处理是阻塞的,没有起到多线程的效果,是线程运行的。效果如下

 疑问二:如果不使用join可以吗?

 答案是可以的,但是,当主线程结束后,在实际使用中不会这样用,主线程结束后,子线程就是放养状态,不知道什么时候才结束掉,不方便管理。

 效果如下:

 另外,join可以设置等待时间,使用参数timeout,timeout设置的时间到了后,主线程得到使用权,主线程结束。

 方法二,继承Thread来实现多线程。其实就是重写Thread里面的run方法来实现多线程

# _*_ coding: utf-8 _*_

import time
from threading import Thread, current_thread


class Demo(Thread):

    def run(self):
        print(f'子线程{self.name}开始...')  # 继承Thread后, 可以调Thread的方法name来获取当前线程名字
        time.sleep(2)
        print(f'子线程{self.name}结束...')


if __name__ == '__main__':
    print('主线程开始...')
    threads = [Demo() for _ in range(3)]  # 创建3个线程对象
    for t in threads:
        t.start()

    for t in threads:
        t.join()

    print('主线程结束...')

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/966776.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号