多任务编程-线程学习笔记

本文介绍了Python中的多线程使用,包括创建线程、传递参数、线程间的无序执行以及如何通过全局变量共享数据。还讨论了互斥锁在确保数据准确性中的作用,防止并发访问导致的问题,并给出了死锁的概念和示例,强调了正确释放锁的重要性。

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

1.多线程的使用:

#1.导入线程模块
import threading
import time

def sing():
    #获取当前线程
    current_thread = threading.current_thread()
    print("sing:", current_thread)

    for i in range(3):
        print("唱歌中...")
        time.sleep(0.2)

def dance():
    #获取当前线程
    current_thread = threading.current_thread()
    print("dance:", current_thread)

    for i in range(3):
        print("跳舞中...")
        time.sleep(0.2)

if __name__ == '__main__':

#获取当前线程
    current_thread = threading.current_thread()
    print("main_thread:", current_thread)


#2.创建子线程
    sing_thread = threading.Thread(target=sing, name="sing_thread")
    dance_thread = threading.Thread(target=dance, name="dance_thread")
#3.启动子线程执行对应的任务
    sing_thread.start()
    dance_thread.start()

2.线程执行带有参数的任务:

import threading

def show_info(name, age):
    print("name: %s age: %d" % (name, age))

if __name__ == '__main__':
    # #创建子线程
    # #以元组方式传参,要保证元组里元素的顺序和函数的参数顺序一致
    # sub_thread = threading.Thread(target=show_info, args=("李四", 20))
    # #启动线程执行对应的任务
    # sub_thread.start()

    #以字典的方式传参,要保证字典里的key和函数的参数名保持一致
    sub_thread = threading.Thread(target=show_info, kwargs={"name": "王五", "age": 30})
    ##启动线程执行对应的任务
    sub_thread.start()

3.线程之间的执行是无序的:

import threading
import time

def task():
    time.sleep(1)
    #获取当前线程
    print(threading.current_thread())

if __name__ == '__main__':
    #循环创建大量线程,测试线程之间是否无序
    for i in range(20):
        #每循环一次创建一个子线程
        sub_thread = threading.Thread(target=task)
        #启动子线程执行对应的任务
        sub_thread.start()

    #线程之间执行是无序的

4.线程之间共享全局变量:

import threading
import time

#定义全局变量
g_list = []

#添加数据的任务
def add_data():
    for i in range(3):
        #每循环一次把数据添加到全局变量
        g_list.append(i)
        print("add:", i)
        time.sleep(0.2)

        #代码执行到此,说明添加数据完成
    print("添加数据完成:", g_list)

#读取数据的任务
def read_data():
    print(g_list)

if __name__ == '__main__':
    #创建添加数据的子线程
    add_thread = threading.Thread(target=add_data)
    #创建读取数据的子线程
    read_thread = threading.Thread(target=read_data)

    #启动线程执行对应的任务
    add_thread.start()
    #time.sleep(1)
    #当前线程等待添加数据的子线程执行完成以后代码在继续执行
    add_thread.join()
    read_thread.start()

#结论:线程之间共享全局变量

5.互斥锁:

import threading

#全局变量
g_num = 0

#创建互斥锁
lock = threading.Lock()



#循环100万次执行的任务
def task1():
    #上锁
    lock.acquire()
    for i in range(1000000):
        global g_num
        g_num = g_num + 1

    #代码执行到此,说明数据计算完成
    print("task1:", g_num)
    #释放锁
    lock.release()

def task2():
    #上锁
    lock.acquire()
    for i in range(1000000):
        #每循环一次给全局变量+1
        global g_num
        g_num = g_num + 1

    #代码执行到此,说明数据计算完成
    print("task2:", g_num)
    #释放锁
    lock.release()

if __name__ == '__main__':
    #创建两个子线程
    first_thread = threading.Thread(target=task1)
    second_thread = threading.Thread(target=task2)

    #启动线程执行任务
    first_thread.start()
    #线程等待,让第一个线程先执行,第二个线程后执行,保证数据不会有问题

    second_thread.start()

    #互斥锁可以保证同一时刻只有一个线程去执行代码,能够保证全局变量的数据没有问题
    #线程等待和互斥锁都是把多任务改成单任务去执行,保证了数据的准确性,但是执行性会下降

6.死锁:

#死锁:一直等待对方释放锁
import threading

#创建互斥锁
lock = threading.Lock()

#需求:多线程同时根据下标在列表中取值,要保证同一时刻只能有一个线程去取值

def get_value(index):
    #上锁
    lock.acquire()
    my_list = [1, 4, 6]
    #判断下标是否越界
    if index >= len(my_list):
        print("下标越界:", index)
        #取值不成功,也需要释放互斥锁,不要影响后面的线程去取值
        #锁需要在合适的地方进行释放,防止死锁
        lock.release()
        return

    #根据下标取值
    value = my_list[index]
    print(value)
    #释放锁
    lock.release()

if __name__ == '__main__':
    #创建大量线程,同时执行根据下标取值的任务
    for i in range(10):
        #每循环一次,创建一个子线程
        sub_thread = threading.Thread(target=get_value, args=(i,))
        #启动线程执行任务
        sub_thread.start()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值