实用:python中的线程

这篇博客详细探讨了Python中的线程使用,包括线程执行顺序、主线程与子线程的关系、进程查看、start与run的区别、线程安全问题、daemon和non-daemon线程的特性、线程的join方法以及线程中局部变量的处理,最后讨论了线程的延迟和取消操作,为理解和应用Python线程提供了实用指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import threading
import time


def worker1(n:int):
    for _ in range(n):
        time.sleep(0.5)
        print('welcome python')
    print('thead over')


def worker2(n:int):
    i = 0
    while True:
        # for _ in range(10):
        if i > n:
            # break
            raise Exception('New Exception')
        time.sleep(0.5)
        print('welcome python....')
        i += 1
    print('thead over....')


t = threading.Thread(target=worker1, name='w1',args=(5,))
t.start()

t = threading.Thread(target=worker2, name='w2',kwargs={'n':5})
t.start()

运行结果:

welcome python
welcome python....
welcome python....
welcome python
welcome python
welcome python....
welcome python....
welcome python
welcome python....
welcome python
thead over
welcome python....
Exception in thread w2:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "/home/yzx/PycharmProjects/cmdb/thread.py", line 18, in worker2
    raise Exception('New Exception')
Exception: New Exception

线程执行顺序:

import threading
import time

def worker1(n=5):
    print('sub = ',threading.current_thread())
    print('sub main1 = ',threading.main_thread())
    for _ in range(n):
        time.sleep(0.5)
        print('welcome python')

    print('sub main2 = ', threading.main_thread())
    print('thread over')

print('main1 = ',threading.current_thread())

t = threading.Thread(target=worker1, name='w1')
t.start()

print('main2 = ',threading.current_thread())

运行结果:

/usr/bin/python3.5 /home/yzx/PycharmProjects/cmdb/thread.py
main1 =  <_MainThread(MainThread, started 140531765335808)>
sub =  <Thread(w1, started 140531741116160)>
sub main1 =  <_MainThread(MainThread, started 140531765335808)>
main2 =  <_MainThread(MainThread, started 140531765335808)>
welcome python
welcome python
welcome python
welcome python
welcome python
sub main2 =  <_MainThread(MainThread, stopped 140531765335808)>
thread over

主线程和子线程

import threading
import time

def worker1(n=5):
    print('sub = ',threading.current_thread())
    print('sub main1 = ',threading.main_thread())
    print('sub thread ID = ', threading.get_ident())
    print(threading.active_count())
    print('sub thread list = ',threading.enumerate())
    for _ in range(n):
        time.sleep(0.5)
        print('welcome python')

    print('sub main2 = ', threading.main_thread())
    print('thread over')

print('main1 = ',threading.current_thread())

t = threading.Thread(target=worker1, name='w1')
t.start()

print('main2 = ',threading.current_thread())

print('main thread ID = ',threading.get_ident())
print('main thread list = ',threading.enumerate())

运行结果:

main1 =  <_MainThread(MainThread, started 140687047280384)>
main2 =  <_MainThread(MainThread, started 140687047280384)>
main thread ID =  140687047280384
main thread list =  [<_MainThread(MainThread, started 140687047280384)>, <Thread(w1, started 140687023060736)>]
sub =  <Thread(w1, started 140687023060736)>
sub main1 =  <_MainThread(MainThread, stopped 140687047280384)>
sub thread ID =  140687023060736
2
sub thread list =  [<_MainThread(MainThread, stopped 140687047280384)>, <Thread(w1, started 140687023060736)>]
welcome python
welcome python
welcome python
welcome python
welcome python
sub main2 =  <_MainThread(MainThread, stopped 140687047280384)>
thread over

查看进程:

import threading
import time
def showinfo():
    print('current thread = {}'.format(threading.current_thread()))
    print('main thread = {}'.format(threading.main_thread()))
    print('active thread  = {}'.format(threading.enumerate()))
    print('active thread count = {}'.format(threading.active_count()))

def worker1(n=5):
    count = 0
    showinfo()
    while True:
        if count > 5:
            break

        time.sleep(1)
        count += 1
        print('I am working')


print('main1 = ', threading.current_thread())

t = threading.Thread(target=worker1, name='w1')
t.start()

运行结果:

main1 =  <_MainThread(MainThread, started 139953807304448)>
current thread = <Thread(w1, started 139953783084800)>
main thread = <_MainThread(MainThread, stopped 139953807304448)>
active thread  = [<_MainThread(MainThread, stopped 139953807304448)>, <Thread(w1, started 139953783084800)>]
active thread count = 2
I am working
I am working
I am working
I am working
I am working
I am working

start 和 run的区别

import threading
import time

class Mythread(threading.Thread):

    def start(self) -> None:
        print('start')
        super().start()

    def run(self) -> None:
        print('run')
        super().run()


def worker1(n=5):
    count = 0

    while True:
        if count > 5:
            break

        time.sleep(0.5)
        count += 1
        print('I am working')


t = Mythread(target=worker1, name='w1')
t.start()
print('====================================')
t = Mythread(target=worker1, name='w2')  #由于start只能调用一次,所以需要新生成一个线程才能真正重复
t.start()
# t.run()

运行结果:

start
run
====================================
start
run
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working

线程的安全

import threading
import logging
logging.basicConfig(level=logging.INFO)


def worker1():
    for x in range(5):
        msg = "{} is running".format(threading.current_thread())
        logging.info(msg)  # 单独起了一个线程在跑
        print(threading.enumerate()) # 这个打印跟上面的输出会交叉输出打印
    print('worker1 end')

threading.Thread(target=worker1, name='worker1-{}'.format(0), daemon=False).start()

运行结果:

[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
worker1 end
INFO:root:<Thread(worker1-0, started 140034061784832)> is running

线程的daemon和non daemon

import threading
import logging
logging.basicConfig(level=logging.INFO)

def worker1():
    threading.Thread(target=worker2,name='worker2-{}'.format(0),daemon=True).start()
    for x in range(5):
        msg = "{} is running".format(threading.current_thread())
        logging.info(msg) #单独起了一个线程在跑
        # print(threading.enumerate()) # 这个打印跟上面的输出会交叉输出打印
    print('worker1 end')

def worker2():
    for x in range(1000):
        msg = "----------{} is running".format(threading.current_thread())
        logging.info(msg) #单独起了一个线程在跑

    print('worker2 end')

threading.Thread(target=worker1,name='worker1-{}'.format(0),daemon=False).start()

运行结果:

worker1 end
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running

线程等待和阻塞(join):

import threading
import logging
import time
logging.basicConfig(level=logging.INFO)


def worker1():
    for x in range(3):
        msg = "{} is running".format(threading.current_thread())
        logging.info(msg)  # 单独起了一个线程在跑
        t = threading.Thread(target=worker2, name='worker1-{}'.format(0), daemon=True)
        t.start()
        t.join() #worker1要等worker2执行完

    print('worker1 end')


def worker2():
    for x in range(5):
        msg = "----------{} is running".format(threading.current_thread())
        logging.info(msg)  # 单独起了一个线程在跑
    print('worker2 end')


t = threading.Thread(target=worker1, name='worker1-{}'.format(0), daemon=True)
t.start()
t.join() #主线程要等worker1执行完成

print('main end')

运行结果:

INFO:root:<Thread(worker1-0, started daemon 140545885087488)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
worker2 end
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
INFO:root:<Thread(worker1-0, started daemon 140545885087488)> is running
worker2 end
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:<Thread(worker1-0, started daemon 140545885087488)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
worker2 end
worker1 end
main end

线程中的局部变量:
传统:

import threading
import time

class A:
    def __init__(self,x):
        self.x = x

a = A(0)

def worker():
    a.x = 0
    for i in range(10):
        time.sleep(0.001)
        a.x += 1
    print(threading.current_thread(),a.x)

for i in range(10):
    threading.Thread(target=worker).start()

运行结果:

<Thread(Thread-3, started 140696810497792)> 61
<Thread(Thread-5, started 140696793712384)> 63
<Thread(Thread-4, started 140696802105088)> 64
<Thread(Thread-2, started 140696818890496)> 65
<Thread(Thread-1, started 140696827283200)> 67
<Thread(Thread-6, started 140696785319680)> 71
<Thread(Thread-7, started 140696776926976)> 72
<Thread(Thread-8, started 140696768534272)> 75
<Thread(Thread-9, started 140696283510528)> 76
<Thread(Thread-10, started 140696275117824)> 78

改进:

import threading
import time

a = threading.local()

def worker():
    a.x = 0
    for i in range(10):
        time.sleep(0.001)
        a.x += 1
    print(threading.get_ident(),a.__dict__)
    print(threading.current_thread(),a.x)

for i in range(10):
    threading.Thread(target=worker).start()

运行结果:

140359073281792 {'x': 10}
<Thread(Thread-1, started 140359073281792)> 10
140358994360064 {'x': 10}
<Thread(Thread-2, started 140358994360064)> 10
140358985967360 {'x': 10}
<Thread(Thread-3, started 140358985967360)> 10
140358969181952 {'x': 10}
140358977574656 {'x': 10}
<Thread(Thread-5, started 140358969181952)> 10
<Thread(Thread-4, started 140358977574656)> 10
140358960789248 {'x': 10}
<Thread(Thread-6, started 140358960789248)> 10
140358952396544 {'x': 10}
<Thread(Thread-7, started 140358952396544)> 10
140358944003840 {'x': 10}
<Thread(Thread-8, started 140358944003840)> 10
140358457489152 {'x': 10}
<Thread(Thread-9, started 140358457489152)> 10
140358449096448 {'x': 10}
<Thread(Thread-10, started 140358449096448)> 10

线程的延迟和取消

import threading
import time

def add(x, y):
    print(x + y)


t = threading.Timer(10, add, args=(4, 5))  #延迟时间
t.start()

time.sleep(2)
t.cancel() #可以放在start前面
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值