5

线程(Thread)基本用法 - 余生没有余生

 1 year ago
source link: https://www.cnblogs.com/lihongtaoya/p/16862244.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一.线程的调用

def run_01():
    for i in range(6, 10):
        print("test01", i)
        time.sleep(1)


th_01 = threading.Thread(target=run_01)  # 创建线程
th_01.start()  # 启动线程

for i in range(0, 5):
    print("main", i)
    time.sleep(1)

threading中最主要的类就是Thread,我们可通过实例化Thread类来创建一个子线程,target参数为运行的事件。

start()方法为启动线程,线程运行结束或报异常时自动会结束线程。

程序默认在主线程上运行,不做任何操作的话,子线程和主线程是同步进行的。

1668630-20221106110710521-242509414.png
def run_01(a):
    for i in range(6, 10):
        print("test01", i)
        time.sleep(1)


th_01 = threading.Thread(target=run_01, args=("test",))  # 创建线程
th_01.start()  # 启动线程

若运行的事件有参数时,我们可通过args传入一个元组入参,也可通过kwargs传入字典类型。

def run_01(a):
    for i in range(6, 10):
        print("test01", i)
        time.sleep(1)


th_01 = threading.Thread(target=run_01, kwargs={"a": "test"})  # 创建线程
th_01.start()  # 启动线程

key值要与参数值保持一致。

def run_01(a, b):
    for i in range(6, 10):
        print("test01", i)
        time.sleep(1)


th_01 = threading.Thread(target=run_01, args=(1, 2))  # 创建线程
# or
# th_01 = threading.Thread(target=run_01, kwargs={"a": "test", "b": 1})  # 创建线程
th_01.start()  # 启动线程

和单个入参差不多,多传入一个参数即可。

二.设置线程名称,获取线程状态

1.子线程名称默认是Thread-1,Thread-2.....,我们可通过Thread类中name属性设置线程名,

def run():
    for i in range(0, 5):
        print(i)


thread = threading.Thread(target=run, name='test')  # name设置线程名
print(thread.name, thread.getName())  # name,getname()方法获取线程名

通过name属性和getName()方法获取线程名。修改/设备线程名也可通过setName()方法设置。

thread = threading.Thread(target=run, name='test')  # name设置线程名
thread.setName("updateThreadName")
print(thread.name, thread.getName())  # name,getName()方法获取线程名

2.is_alive()为获取线程当前的运行状态

def run():
    for i in range(0, 5):
        print(i)


thread = threading.Thread(target=run, name='test')  # name设置线程名
thread.start()
bol = thread.is_alive()  # 为true时表示正在运行,为false时停止运行
print(bol)

三.主/子线程执行顺序

1.默认情况下主/子线程会同时执行,主线程会等待子线程结束后再结束。

def run():
    for i in range(0, 5):
        print("thread", i)
        time.sleep(2)


if __name__ == '__main__':
    thread = threading.Thread(target=run)
    thread.start()
    for i in range(5, 10):
        print("main", i)
        time.sleep(1)

2.Thread类中有个daemon属性可控制执行结果

if __name__ == '__main__':
    thread = threading.Thread(target=run,daemon=True)
    thread.start()
    for i in range(5, 10):
        print("main", i)
        time.sleep(1)

创建子线程时我们将daemon设置为True,可以看出主线程结束后子线程也会结束运行,

不会等待子线程结束后再结束。也可通过setDaemon()方法设置。

if __name__ == '__main__':
    thread = threading.Thread(target=run)
    thread.setDaemon(True)
    thread.start()
    for i in range(5, 10):
        print("main", i)
        time.sleep(1)

四.join()用法

1.join()为堵塞主线程执行,优先执行子线程,等子线程执行完后再去执行主线程。

def run():
    for i in range(0, 5):
        print("thread1", i)
        time.sleep(1)


def run2():
    for i in range(0, 5):
        print("thread2", i)
        time.sleep(1)


if __name__ == '__main__':
    thread = threading.Thread(target=run)
    thread2 = threading.Thread(target=run2)
    thread.start()
    thread.join()  # 开始堵塞主线程,只执行thread线程
    thread2.start()

    for i in range(5, 10):
        print("main", i)
        time.sleep(1)

2.join(timeout=None)中timeout参数

timeout默认为None,可传递秒数,设置堵塞主线程的时间,timeout秒后不管子线程有没有运行完都会执行主线程。

thread.join(timeout=2.0)

五.Event()方法的使用

我们都知道一个进程有多个线程,多个线程之间的资源是共享的,那么如果多个线程去修改同

一个资源数据,就会出现数据错乱的情况。Event类可以去堵塞线程的运行,我们先来看下Event()的几个方法。

1.实例化Event()类

event = threading.Event()

Event()中有个_flag的私有属性,默认为false,表示堵塞

2.wait()调用后表示开始堵塞

event.wait(timeout=2.0)  # 调用该方法后,该线程会被堵塞,timeout为堵塞时间

3.set()方法设置flag为true,表示结束堵塞

event.set()  # 设置self._flag = True

4.清除设置,flag值恢复false,继续堵塞

event.clear()  # self._flag = False

5.is_set()查看flag的值

print(event.is_set())  # 查看当前_flag的值
import threading
import time


def run(event):
    print("当前flag的值", event.is_set())
    event.wait()  # 开始堵塞
    for i in range(1, 6):
        print(i)
        time.sleep(1)
        if event.is_set() == False:
            break


event = threading.Event()  # self._flag = False
thread = threading.Thread(target=run, args=(event,))
thread.start()
print("\n开始堵塞2s")
time.sleep(2)
event.set()  # 设置self._flag = True
print("结束堵塞,运行2s")
time.sleep(2)
print("结束运行,跳出for循环")
event.clear()  # self._flag = False

上述中,子线程执行到event.wait()时就开始进行堵塞,主线程等待2s后调用set()方法使子线程继续运行,

子线程循环两次后主线程调用clear()设置flag值为false,子线程if判断跳出循环,运行结束。

文章来源:https://www.cnblogs.com/lihongtaoya/ ,请勿转载

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK