python通过threading实现多线程(一)

多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multithreading)处理器。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理(Multithreading)”。

在python中如何实现呢?

python中实现这个功能的是threading模块,这个模块是一个内置模块,不需要安装。threading 模块中最核心的内容是 Thread 这个类。

我们要创建 Thread 对象,然后让它们运行,每个 Thread 对象代表一个线程,在每个线程中我们可以让程序处理不同的任务,这就是多线程编程。PS:需要注意的是,程序在运行的时候,默认都是在主线程上运行,且只能运行一个主线程。

话不说多,来实操吧~

1、首先我们要引入这个模块:

import threading

然后看一下Thread的方法:

<code>def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)/<code>

一定要注意的是,只有给target设置参数,而后通过start命令调用,这个多线程才能开始执行。

2、看一下代码示例:

<code>import threading
import time


def jier():
    for i in range(5):
        print('线程1_' + str(i))

        time.sleep(1)


def suner():
    for i in range(5):
        print('线程2_' + str(i))
        time.sleep(1)


thread = threading.Thread(target=jier)
thread.start()
thread_1 = threading.Thread(target=suner)
thread_1.start()


for i in range(5):
    print('主线程_' + str(i))
    time.sleep(1)/<code>

运行结果如下:

python通过threading实现多线程(一)

上面的代码含义很简单,在运行主线程的时候,同时运行线程一和线程二;

3、Thread的name参数

每一个线程都应该有属于自己的名字, 有一个“name”的参数进行控制,如果在进行方法构建的过程中不进行设定的话,默认的配置是“Thread-N”,示例如下:

<code>import threading
import time


def jier():
    for i in range(5):
        print(threading.current_thread().name + '线程1_' + str(i))
        time.sleep(1)


def suner():
    for i in range(5):
        print(threading.current_thread().name + '线程2_' + str(i))
        time.sleep(1)


thread = threading.Thread(target=jier)
thread.start()
thread_1 = threading.Thread(target=suner)
thread_1.start()


for i in range(5):
    print('主线程_' + str(i))
    time.sleep(1)/<code>

结果如下:

python通过threading实现多线程(一)

根据如上代码,可以看到我们在构建的过程中添加了一个命令,即“threading.current_thread().name”,然后再调用Thread创建对象的时候没有变化,即会出现如上所示的运行结果;

那么接下来我们将在Thread创建对象的时候输入“name”命令,再看下情况:

<code>thread = threading.Thread(target=jier, name='哈哈哈~')
thread.start()
thread_1 = threading.Thread(target=suner, name='嘿嘿嘿~')
thread_1.start()/<code>

运行结果如下:

python通过threading实现多线程(一)


4、Thread的生命周期

在我们使用Thread创建对象,且通过start命令进行调用,Thread会处于正常运行阶段,如果遇到异常或运行结束会终止。这个时候我们没法判断是否处于正常状态中,故而我们可以采用“thread.isAlive()”来获取他的生命周期,示例代码如下:

<code>import threading
import time


def jier():
    for i in range(3):
        print(threading.current_thread().name + '线程1_' + str(i))
        time.sleep(1)


def suner():
    for i in range(3):
        print(threading.current_thread().name + '线程2_' + str(i))
        time.sleep(1)


thread = threading.Thread(target=jier, name='哈哈哈~')
thread.start()
thread_1 = threading.Thread(target=suner, name='嘿嘿嘿~')
thread_1.start()


for i in range(3):
    print('主线程_' + str(i))
    print('thread 的生命周期' + thread.name, thread.isAlive())
    print('thread_1 的生命周期' + thread.name, thread_1.isAlive())
    time.sleep(2)/<code>

从以上代码发现,我们改动了time.slppe()的时间,因为要给出程序一些时间,来终止Thread的对象,以及检查该对象的时间差,故而进行了时间层次的控制。

运行结果如下:

python通过threading实现多线程(一)


5、线程运行阻塞

可以看到,如果间隔时间一致的话,主线程和多线程是同时进行的,那么有没有一种方法可以对于一个线程进行阻塞呢?

采用的是Thread的join方法:

<code>join(self, timeout=None)/<code> 

PS:join的参数是一个浮点数,单位是S;也可以不填这个参数,那么就是默认等待此阻塞之前的程序运行完毕之后再运行接下来的线程;

示例代码如下:

<code>import threading
import time

def jier():
    for i in range(3):
        print(threading.current_thread().name + '线程1_' + str(i))
        time.sleep(1)


def suner():
    for i in range(3):
        print(threading.current_thread().name + '线程2_' + str(i))
        time.sleep(1)


thread = threading.Thread(target=jier, name='哈哈哈~')
thread.start()
thread.join(timeout=1)
thread_1 = threading.Thread(target=suner, name='嘿嘿嘿~')
thread_1.start()
thread_1.join()


for i in range(3):
    print('主线程_' + str(i))
    print('thread 的生命周期' + thread.name, thread.isAlive())
    print('thread_1 的生命周期' + thread.name, thread_1.isAlive())
    time.sleep(2)/<code>

根据以上代码,可以看到,我们将thread_1让其阻塞了1S,thread进行了默认参数的阻塞,那么这种情况下的运行结果是怎样的呢?

python通过threading实现多线程(一)

可以根据运行结果看到,确实是join阻塞的线程运行完毕之后才进行了下面的主线程的运行。


6、Thread的daemon参数

这个参数的作用什么呢?默认是False;

即表示,在程序运行过程中,我们知道肯定有一个主线程,那么如果daemon设置是False的话,那么主线程在运行完自己的内容之后,不会立刻终止主程序,会等待其他线程运行结束之后,主线程才会关闭。

接下来我们通过时间控制来进行模拟,代码如下:

<code>import threading
import time


def jier():
    for i in range(3):
        print(threading.current_thread().name + '线程1_' + str(i))
        time.sleep(1)


def suner():
    for i in range(3):
        print(threading.current_thread().name + '线程2_' + str(i))
        time.sleep(1)


thread = threading.Thread(target=jier, name='哈哈哈~')
thread.start()
# thread.join(timeout=1)
thread_1 = threading.Thread(target=suner, name='嘿嘿嘿~')
thread_1.start()
# thread_1.join()


for i in range(3):
    print('主线程_' + str(i))
    print('thread 的生命周期' + thread.name, thread.isAlive())
    print('thread_1 的生命周期' + thread.name, thread_1.isAlive())
    time.sleep(0.5)/<code>

以上代码可以看到,我们修改了主线程的时间,让主线程先运行完毕了,那么结果如何呢?

运行结果如下:

python通过threading实现多线程(一)

可以看到,在主线程运行结束的时候,多线程还在运行,此程序并没有结束,那么我们进行daemon的修改之后会变成怎样的结果呢?

<code>import threading
import time


def jier():
    for i in range(3):
        print(threading.current_thread().name + '线程1_' + str(i))
        time.sleep(1)


def suner():
    for i in range(3):
        print(threading.current_thread().name + '线程2_' + str(i))
        time.sleep(1)


thread = threading.Thread(target=jier, name='哈哈哈~', daemon=True)
thread.start()
# thread.join(timeout=1)
thread_1 = threading.Thread(target=suner, name='嘿嘿嘿~', daemon=True)
thread_1.start()
# thread_1.join()


for i in range(3):
    print('主线程_' + str(i))
    print('thread 的生命周期' + thread.name, thread.isAlive())
    print('thread_1 的生命周期' + thread.name, thread_1.isAlive())
    time.sleep(0.5)/<code>

从以上代码可以看出,我们在调用Thread构建对象的时候,添加了daemon参数,并设置为True;

运行结果如下:

python通过threading实现多线程(一)

从运行结果可以看出,当主线程运行完毕之后,此程序立刻终止了,并没有等待多线程的继续运行。


7、自定义继承类Thread

首先要继承threading的Thread方法,然后重写run命令,并进行覆盖。

<code>import threading
import time


def jier():

    for i in range(3):
        print(threading.current_thread().name + '线程1_' + str(i))
        time.sleep(1)


class suner(threading.Thread):
    def __init__(self, name = None):
        threading.Thread.__init__(self, name=name)


    def run(self):
        for i in range(3):
            print(threading.current_thread().name + '线程2_' + str(i))
            time.sleep(1)


# def suner():
#     for i in range(3):
#         print(threading.current_thread().name + '线程2_' + str(i))
#         time.sleep(1)


thread = threading.Thread(target=jier, name='哈哈哈~', daemon=True)
thread.start()
# thread.join(timeout=1)
thread_1 = threading.Thread(target=suner, name='嘿嘿嘿~', daemon=True)
thread_1.start()
# thread_1.join()


for i in range(3):
    print('主线程_' + str(i))
    print('thread 的生命周期' + thread.name, thread.isAlive())
    print('thread_1 的生命周期' + thread.name, thread_1.isAlive())
    time.sleep(0.5)/<code>

可以看到我们重写了run命令,结果如下:

python通过threading实现多线程(一)

运行结果没什么差别,但是我们这次可以说是自行构建的方法,后期可以根据自行的实际情况来进行判断。

继续加油~~~



分享到:


相關文章: