Python 的游戏开发专区python学习之路大数据 爬虫Python AI Sql

python 多线程总述

2019-07-06  本文已影响1人  Alcazar

线程

什么是线程

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。一个线程是一个execution context(执行上下文),即一个cpu执行时所需要的一串指令。

线程的工作方式

CPU会给你一个在同一时间能够做多个运算的幻觉,实际上它在每个运算上只花了极少的时间,本质上CPU同一时刻只干了一件事。它能这样做就是因为它有每个运算的execution context。就像你能够和你朋友共享同一本书一样,多任务也能共享同一块CPU。


启动多个线程(函数实现)

Python提供了一个内置模块 threading.Thread,可以很方便地让我们创建多线程。 threading.Thread() 一般接收两个参数:

【举个例子】:

import threading
import time
def run(n):
    print("task ",n )
    time.sleep(2)

# run("t1")
# run("t2")
t1 = threading.Thread(target=run,args=("t1",))#生成一个线程实例
t2 = threading.Thread(target=run,args=("t2",))
t1.start()
t2.start()

【输出】:
task  t1
task  t2

【解释】由于每个方法都有单独的进程,会同时开始执行,上面代码会同时输出

启动多个线程(类实现)

相比较函数而言,使用类创建线程,会比较麻烦一点。 首先,我们要自定义一个类,对于这个类有两点要求:

# 类方法
class MYThread(threading.Thread):

    def __init__(self,n):
        super().__init__()
        self.n = n

    def run(self):
        print("task",self.n)
        time.sleep(2)
        print("{} finished\n".format(self.n))

t1 = MYThread('t1')
t2 = MYThread('t2')


t = time.time()
t1.start()
t2.start()

# 调用者会等待该线程结束后,再执行;

t2.join()

t1.join()

t1 = time.time()

print('main finished...')
print("线程所耗时间为:",t1 - t)

【输出】

task t1
task t2
t1 finished
t2 finished


main finished...
线程所耗时间为: 2.0015668869018555

【关于 join() 函数】

import threading
import time
def run(n):
    print("task ",n )
    time.sleep(2)
    print("task done",n)

start_time = time.time()
for i in range(12):
    t = threading.Thread(target=run,args=("t-%s" %i ,))
    t.start()

print("----------all threads has finished...")
print("cost:",time.time() - start_time)

输出:

task  t-0
task  t-1
task  t-2
task  t-3
task  t-4
task  t-5
task  t-6
task  t-7
task  t-8
task  t-9
task  t-10
task  t-11----------all threads has finished...
cost: 
0.001996278762817383
task donetask done t-2
 t-0
task done t-4task done task done t-3t-1

task done t-7
task done t-9task done 
task done task done t-8
t-5t-6

task donetask done  t-11
t-10

我们知道线程有 就绪、阻塞、运行三种基本状态。

  1. 就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;
  2. 运行状态是指线程占有处理机正在运行;
  3. 阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。

关于【多线程】的小程序

from threading import Thread
import os, time

#计算密集型任务
def work():
    res = 0
    for i in range(100000000):
        res *= i

if __name__ == "__main__":
    l = []
    print("本计算机是",os.cpu_count(),"核 CPU")
    start = time.time()
    for i in range(4):
        p = Thread(target=work)  # 多进程
        l.append(p)
        p.start()
    for p in l:
        p.join()
    stop = time.time()
    print("本计算机计算密集型任务,多线程耗时 %s" % (stop - start))

输出:

本计算机是 8 核 CPU
本计算机计算密集型任务,多线程耗时 25.76108407974243

【关于is_alive()方法】:
可以用来判断一个线程是否结束。

import threading
import time


def run(n):
    print("task ", n)
    time.sleep(2)
    print("task done", n)


start_time = time.time()
t_objs = []  # 存线程实例
for i in range(5):
    t = threading.Thread(target=run, args=("t-%s" % i,))
    t.start()
    t_objs.append(t)  # 为了不阻塞后面线程的启动,不在这里join,先放到一个列表里

for t in t_objs:
    print(t.is_alive())

for t in t_objs:  # 循环线程实例列表,等待所有线程执行完毕
    t.join()

for t in t_objs:
    print(t.is_alive())

print("----------all threads has finished...")
print("cost:", time.time() - start_time)

输出:

task  t-0
task  t-1
task  t-2
task  t-3
task True
True
True
True
True
 t-4
task done task done t-1
t-0
task done t-4task done 
task done t-3t-2

False
False
False
False
False
----------all threads has finished...
cost: 2.0031514167785645
上一篇下一篇

猜你喜欢

热点阅读