python培训第三课(多线程)

本文介绍了Python中多线程的概念及实现方式,包括通过导入threading模块创建线程、使用锁(Lock)确保线程安全以及递归锁(Rlock)的应用。通过银行转账的例子解释了线程同步的重要性,并给出了B站视频资源作为深入学习的参考。同时,提出了使用类创建线程以实现并发输出日期和打印姓名的作业。

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

多线程

是python程序中实现多任务的一种方式。线程是程序执行的最小单位。同属一个进程的多个线程共享进程所拥有的的全部资源。

步骤:

a 导入线程模块 import threading

b 创建子线程并指定执行的任务

sing_thread=threading.Thread(target=sing)

c启动线程执行任务

sing_thread.start()

线程执行带有参数的任务时,可用args(以元组方式传参)或 kwargs(以字典方式传参)

import threading  # 导入线程模块
import time    # 导入时间模块


def sing(x):   # 构造函数
    for i in range(x):
        print("唱歌")
    time.sleep(2)  # 休眠2秒


def dance(y):   # 构造函数
    for i in range(y):
        print("跳舞")
    time.sleep(2)  # 休眠2秒


t1=threading.Thread(target=sing, args=(1,))  # 创建子进程t1并指定执行的任务sing,使用args传参
t2 = threading.Thread(target=dance, kwargs={"y": 2})  # 创建子进程t2并指定执行的任务dance,使用kwargs传参
# 启动线程执行任务
t1.start()
t2.start()

使用类来创建多线程

import threading  # 导入线程模块
import time  # 导入时间模块


class MyThread(threading.Thread):  # 定义类,继承自threading.Thread这个基类
    def __init__(self, n):  # 初始化 ,并传递参数n
        super(MyThread, self).__init__()
        self.n = n

    def run(self):  # 启动线程的函数,此种方式创建多线程,函数名只能为run,不能自定义
        print('以类的方式创建多线程', self.n)
        time.sleep(3)  


r1 = MyThread(11)  # 实例化对象
r2 = MyThread(22)

r1.start()  # 启动线程
r2.start()

多线程的特性 : 主线程会等待所有子线程结束之后才会结束程序 

线程锁

为什么需要线程锁?
多个线程对同一个数据进行修改时, 可能会出现不可预料的情况.
例如实现银行转账功能,money += 1 这句其实有三个步骤 money; money+1; money=money+1;假如这三步骤还没完成money-=1的线程就开始执行了,后果可想而知,money的值肯定时乱的
如何实现线程锁?
1. 实例化一个锁对象;
lock = threading.Lock()
2. 操作变量之前进行加锁
lock.acquire()
3. 操作变量之后进行解锁
lock.release()

B站线程锁例子:

import threading  # 导入线程模块


def test():  # 构造函数
    global x  # 全局变量x
    lock.acquire()  # 申请一把线程锁
    x += 1
    lock.release()  # 操作x之后将线程锁释放


if __name__ == '__main__':
    x = 0
    res = []  # 定义一个空列表
    lock = threading.Lock()  # 对线程里面的锁进行实例化

    for i in range(100):  # 起100个多线程
        t = threading.Thread(target=test)
        t.start()
        res.append(t)  # 将线程加入列表

        for t in res:  # 遍历列表
            t.join()
            print(x)  # 输出线程个数 100

例子2:银行存钱和取钱

import threading


#  银行存钱和取钱
def add(lock):
    global money  # 生命money为全局变量
    for i in range(1000000):
        # 2. 操作变量之前进行加锁
        lock.acquire()
        money += 1  # money;  money+1; money=money+1;
        # 3. 操作变量之后进行解锁
        lock.release()


def reduce(lock):
    global money
    for i in range(1000000):
        # 2. 操作变量之前进行加锁
        lock.acquire()
        money -= 1
        # 3. 操作变量之后进行解锁
        lock.release()


if __name__ == '__main__':
    money = 0
    # 1. 实例化一个锁对象;
    lock = threading.Lock()

    t1 = threading.Thread(target=add, args=(lock,))
    t2 = threading.Thread(target=reduce, args=(lock,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    print("当前金额:", money)

递归锁:锁嵌套时,注意要用 lock= threading.Rlock()

视频网址 69-Python多线程-递归锁_哔哩哔哩_bilibili

import threading


def run1():
    global x
    lock.acquire()
    x += 1
    lock.release()
    return x


def run2():
    global y
    lock.acquire()
    y += 1
    lock.release()
    return y


def run3():
    lock.acquire()
    res1 = run1()
    res2 = run2()
    print(res1, res2)
    lock.release()


if __name__ == '__main__':
    x = 0
    y = 0
    lock = threading.RLock()
    for i in range(50):
        s = threading.Thread(target=run3())
        s.start()

    while threading.activeCount() != 1:
        print(f"正在运行{threading.activeCount()}个线程")

print("程序运行结束")

作业:在一个线程中,每秒循环输出当前的年月日分秒,与此同时,在另一线程中,实现张三的姓名每2秒打印输出4次结束。注意:都需要使用类和继承来实现功能
不使用类创建:

import threading  # 导入线程模块
import time  # 导入时间模块


def date():  # 构造方法
    while True:
        time.sleep(1)  # 休眠1秒
        print(time.strftime('%Y-%m-%d %X'))  # 输出当前时间(年月日分秒)


def run():   # 构造方法
    while True:
        time.sleep(3)  # 休眠3秒
        print("张三")


t1 = threading.Thread(target=date)  # 创建子线程t1并指定执行的任务date
t2 = threading.Thread(target=run)   # 创建子线程t2并指定执行的任务run

t1.start()  # 启动线程
t2.start()

使用类创建:

import time  # 导入线程模块
import threading  # 导入时间模块


class First(threading.Thread):  # 定义First类,继承自threading.Thread这个基类
    def run(self):  # 构造函数
        while True:
            localtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())   # 输出当前时间
            print(localtime)
            time.sleep(1)  # 休眠一秒


class Second(threading.Thread):  # 定义second类,继承自threading.Thread这个基类
    def __init__(self, name):  # 初始化 ,并传递参数name
        super(Second, self).__init__()
        self.name = name

    def run(self):   # 启动线程的函数,此种方式创建多线程,函数名只能为run,不能自定义
        for i in range(4):  # 张三姓名输出4次后结束
            print(self.name)
            time.sleep(0.5)  # 每打印一次后暂停0.5秒


if __name__ == '__main__':
    t1 = First()   # 实例化对象
    t2 = Second("张三")
    t1.start()    # 启动线程执行任务
    t2.start()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值