首页 > 技术文章 > 31、线程

poco 2021-04-27 20:29 原文

一、线程的概念

首先我们学习了进程,进程有很多优点,它提供了多道编程,提高计算机的利用率。很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上:

  • 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
  • 进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。

现在我们发现了进程的缺陷了,而解决的办法就是引入了线程的机制。

线程的特点

进程是资源分配的最小单位,线程是CPU调度的最小单位。每一个进程中至少有一个线程。

线程可以利用进程所拥有的资源执行调度和运算。

同一个进程中的线程共享同一内存空间,但是进程之间是独立的。

线程启动速度快,进程启动速度慢(但是两者运行速度没有可比性)

全局解释器(GIL)锁

全局解释器锁是CPython解释器的一种机制,只有拿到GIL锁的线程才可以执行,所以代表着,同一时刻,在一个进程中,开启多个线程,也只能有一条线程在执行

二、线程的使用

1、如何开启线程

启动线程和启动进程差不多,只是导入的模块不同

# 方式一
from threading import Thread


def task():
    print('我是子线程')


if __name__ == '__main__':
    t = Thread(target=task)
    t.start()

用类的方式也和进程一样,需要重写run方法

# 方式二
from threading import Thread


class MyThread(Thread):
    def run(self) -> None:
        print('我是子线程')


if __name__ == '__main__':
    t = MyThread()
    t.start()

2、Thread类的方法

2-1、Thread实例对象的方法

t.is_alive()  # 判断线程是否存活
t.getName()  # 查看线程的名字,需要打印出来
t.setName()  # 设置线程的名字
t.setDaemon(True)  # 守护线程,与守护进程一样,在start前使用,主进程执行结束,子进程也会结束

2-2、threading模块提供的一些方法

threading.currentThread()  # 返回当前的线程变量。
threading.enumerate()  # 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount()  # 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

3、线程和进程的比较

开线程的资源消耗的资源以及消耗的时间 远远小于进程

from threading import Thread
import time

 
def task():
    time.sleep(0.1)
    print('我是子线程')


if __name__ == '__main__':
    start = time.time()
    t = Thread(target=task)
    t.start()
    t.join()
    print('我是主线程')
    print('运行时间为', time.time() - start)

'''
上面这段代码使用线程执行,运行时间为0.10秒
但如果用进程执行,运行时间为0.18到0.17秒不等
对于计算机来说这0.08秒的时间 已经算很久了
'''

三、线程队列Queue

线程的Queue与进程的Queue一样,是用于实现线程的通信

from threading import Thread
from queue import Queue

def task(q):
    q.put('熊大')  # 存值
    q.put('熊二')


if __name__ == '__main__':
    q = Queue()  # Queue实例化
    t = Thread(target=task, args=(q,))
    t.start()

    print(q.get())  # 取值
    print(q.get())
'''运行结果
熊大
熊二
'''

线程Queue的属性方法与进程基本一致,这里就不多演示了,

另外还有LifoQueue:先进先出PriorityQueue:优先级队列,均是queue下的类

推荐阅读