Python多线程

本文最后更新于 2026年8月21日

线程是进程内部的执行单元,一个进程可以含有不止一个线程,线程是操作系统进行CPU调度的基本单位,同一进程内的线程共享进程的资源,本文讲述关于python线程的创建和用法

Thread

python采用Thread类创建进程,这一点和Java很相似,get_native_id()方法获得进程编号

相比于进程,申请一个线程需要开辟的资源,消耗的时间,都是明显减少的,新开进程相当于工厂新开了分厂,新开线程则类似新招进来了工人

import time
from threading import get_native_id, Thread

def test1():
    for i in range(5):
        print(f't1 index:{i} get_native_id:{get_native_id()}')
        time.sleep(1)

def test2():
    for i in range(5):
        print(f't2 index:{i} get_native_id:{get_native_id()}')
        time.sleep(1)

if __name__ == '__main__':
    print('===start===')
    t1 = Thread(target=test1)
    t2 = Thread(target=test2)
    t1.start()
    t2.start()
    print(f'===end 主线程 get_native_id:{get_native_id()}===')


===start===
t1 index:0 get_native_id:7196
t2 index:0 get_native_id:28000
===end 主线程 get_native_id:8584===
t2 index:1 get_native_id:28000t1 index:1 get_native_id:7196

t2 index:2 get_native_id:28000t1 index:2 get_native_id:7196

t2 index:3 get_native_id:28000t1 index:3 get_native_id:7196

t1 index:4 get_native_id:7196t2 index:4 get_native_id:28000

Thread类有以下参数,与Process十分相似:

  • group 默认为None
  • target 调用对象,默认为None
  • name 线程名,不写会默认
  • args 为目标target传递位置可变(元组)参数
  • kwargs 为目标target传递关键字可变(字典)参数
  • daemon 布尔值,是否为守护线程,默认为None

可通过join()方法,将子线程插队优先执行,这样,子线程打印完成,主线程才最后打印

if __name__ == '__main__':
    print('===start===')
    t1 = Thread(target=test1)
    t2 = Thread(target=test2)
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(f'===end 主线程 get_native_id:{get_native_id()}===')
===start===
t1 index:0 get_native_id:24220
t2 index:0 get_native_id:30604
t1 index:1 get_native_id:24220t2 index:1 get_native_id:30604

t1 index:2 get_native_id:24220
t2 index:2 get_native_id:30604
t1 index:3 get_native_id:24220t2 index:3 get_native_id:30604

t1 index:4 get_native_id:24220
t2 index:4 get_native_id:30604
===end 主线程 get_native_id:25304===

但是子线程打印仍然是争抢的,python中通过RLock对执行进行上锁,谁获取锁,就执行

import time
from threading import get_native_id, Thread, RLock

def test1(lock):
    for i in range(5):
        with lock:
            print(f't1 index:{i} get_native_id:{get_native_id()}')
            time.sleep(1)

def test2(lock):
    for i in range(5):
        with lock:
            print(f't2 index:{i} get_native_id:{get_native_id()}')
            time.sleep(1)


if __name__ == '__main__':
    print('===start===')
    lock = RLock()
    t1 = Thread(target=test1, args=(lock,))
    t2 = Thread(target=test2, args=(lock,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(f'===end 主线程 get_native_id:{get_native_id()}===')
===start===
t1 index:0 get_native_id:30436
t1 index:1 get_native_id:30436
t1 index:2 get_native_id:30436
t2 index:0 get_native_id:25724
t2 index:1 get_native_id:25724
t2 index:2 get_native_id:25724
t2 index:3 get_native_id:25724
t1 index:3 get_native_id:30436
t2 index:4 get_native_id:25724
t1 index:4 get_native_id:30436
===end 主线程 get_native_id:13032===

还可通过继承Thread类实现一个线程

import time
from threading import get_native_id, Thread, RLock

class ProduceThread(Thread):
    def __init__(self, lock, **kwargs):
        super().__init__(**kwargs)
        self.lock = lock

    def run(self):
        for i in range(5):
            with self.lock:
                print(f't1 index:{i} get_native_id:{get_native_id()}')
                time.sleep(1)


class ConsumerThread(Thread):
    def __init__(self, lock, **kwargs):
        super().__init__(**kwargs)
        self.lock = lock

    def run(self):
        for i in range(5):
            with self.lock:
                print(f't2 index:{i} get_native_id:{get_native_id()}')
                time.sleep(1)


if __name__ == '__main__':
    print('===start===')
    lock = RLock()
    t1 = ProduceThread(lock)
    t2 = ConsumerThread(lock)
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(f'===end 主线程 get_native_id:{get_native_id()}===')

"如果文章对您有帮助,可以请作者喝杯咖啡吗?"

微信二维码

微信支付

支付宝二维码

支付宝


Python多线程
https://blog.liuzijian.com/post/2026/03/15/python-thread/
作者
Liu Zijian
发布于
2026年3月15日
更新于
2026年8月21日
许可协议