多线程基本操作

本文介绍了多线程的概念,如何在Python中创建和使用线程,包括通过函数和类的方式。讨论了线程作为CPU资源分配的基本单位,以及在处理并发任务时的角色。文章还提到了线程的常用方法如current_thread和enumerate,并展示了如何获取和设置线程名称。进一步,文章通过示例演示了在共享全局变量时可能出现的竞争条件,并引入锁机制来保证线程安全,确保资源的正确修改和释放。
摘要由CSDN通过智能技术生成

多线程

程序同时执行多个任务

  • 使用线程可以把占据长时间的程序中的任务放到后台去处理。

  • 程序的运行速度可能加快

线程实现方法

线程是CPU分配资源的基本单位。当一程序开始运行,这个程序就变成了一个进程,而一个进程相当于一个或者多个线程。当没有多线程编程时,一个进程相当于一个主线程;当有多线程编程时,一个进程包含多个线程(含主线程)。使用线程可以实现程序大的开发

  • 线程是执行单位,也是最小的资源分配单位

单线程执行程序

def demo1():
    for i in range(5):
        print("demo1:",i)

def demo2():
    for i in range(5):
        print("demo2:",i)
        
if __name__ == '__main__':
    demo1()
    demo2()

修改为多线程之后

import threading

def demo1():
    for i in range(5):
        print("demo1在执行:", i)

def demo2():
    for i in range(5):
        print("demo2在执行:", i)

def main():
    t1 = threading.Thread(target=demo1, name="demo1")
    t2 = threading.Thread(target=demo2, name="demo2")
    t1.start()
    t2.start()

if __name__ == '__main__':
    main()

通过继承的方式实现

from threading import Thread


class Thread_Spider1(Thread):
    def run(self):
        for i in range(5):
            print("子线程开始执行", i)

class Thread_Spider2(Thread):
    def run(self):
        for i in range(5):
            print("子线程开始执行", i)


if __name__ == '__main__':
    t1 = Thread_Spider1()
    t1.start()
    t2 = Thread_Spider2()
    t2.start()
    for i in range(5):
        print("主线程:", i)

线程的常用方法

方法名称

描述

threading.current_thread()

获取当前线程对象

threading.enumerate()

获取当前线程的信息

getName()

获取线程名称

setName(name)

设置线程名称

  • threading.current_thread()

import threading

class Thread_Spider1(threading.Thread):
    def run(self):
        thread = threading.current_thread()
        print(thread)
        # <Thread_Spider1(Thread-1,  started 9172)>
        for i in range(5):
            print("子线程开始执行", i)

class Thread_Spider2(threading.Thread):
    def run(self):
        thread = threading.current_thread()
        print(thread)
        # <Thread_Spider2(Thread-2, started 1304)>
        for i in range(5):
            print("子线程开始执行", i)


if __name__ == '__main__':
    t1 = Thread_Spider1()
    t1.start()
    t2 = Thread_Spider2()
    t2.start()
    for i in range(5):
        print("主线程:", i)
  • threading.enumerate()

import threading

class Thread_Spider1(threading.Thread):
    def run(self):
        for i in range(5):
            print("子线程开始执行", i)

class Thread_Spider2(threading.Thread):
    def run(self):
        for i in range(5):
            print("子线程开始执行", i)


if __name__ == '__main__':
    t1 = Thread_Spider1()
    t1.start()
    t2 = Thread_Spider2()
    t2.start()
    print(threading.enumerate())
    # [<_MainThread(MainThread, started 3088)>, <Thread_Spider1(Thread-1, started 9040)>, <Thread_Spider2(Thread-2, started 			6376)>]
    for i in range(5):
        print("主线程:", i)
  • 修改以及获取名称

了解即可

import threading


class Thread_Spider1(threading.Thread):
    def run(self):
        thread = threading.current_thread()
        print(thread)
        print("线程名称:", thread.getName())
        thread.setName("我的子线程")
        print("修改后的名称:", thread.getName())
        for i in range(5):
            print("子线程开始执行", i)


if __name__ == '__main__':
    t1 = Thread_Spider1()
    t1.start()
    print(threading.enumerate())
    for i in range(5):
        print("主线程:", i)

共享全局变量资源竞争

多个线程同时在完成一个任务的时候发生资源竞争

import threading

num = 100

def func1():
    for i in range(200):
        global num
        if num > 0:
            print("func1-正在输出{}".format(num))
        num -= 1

def func2():
    for i in range(200):
        global num
        if num > 0:
            print("func2-正在输出{}".format(num))
        num -= 1

def func3():
    for i in range(200):
        global num
        if num > 0:
            print("func3-正在输出{}".format(num))
        num -= 1

def start():
    t1 = threading.Thread(target=func1)
    t1.start()  
    t2 = threading.Thread(target=func2)
    t2.start()
    t3 = threading.Thread(target=func2)
    t3.start()

if __name__ == '__main__':
    start()

锁机制

解决多线程访问全局变量的安全性问题
访问全局变量无需加锁,修改时需要加锁,修改完毕之后要释放锁
  • 加锁步骤

创建加锁对象threading.Lock()

加锁acquire()

解锁release()

import threading

num = 100

lock = threading.Lock()
def func1():
    for i in range(200):
        global num
        lock.acquire()
        if num > 0:
            print("func1-正在输出{}".format(num))
        num -= 1
        lock.release()

def func2():
    for i in range(200):
        global num
        lock.acquire()
        if num > 0:
            print("func2-正在输出{}".format(num))
        num -= 1
        lock.release()

def func3():
    for i in range(200):
        global num
        lock.acquire()
        if num > 0:
            print("func3-正在输出{}".format(num))
        num -= 1
        lock.release()

def start():
    t1 = threading.Thread(target=func1)
    t1.start()
    t2 = threading.Thread(target=func2)
    t2.start()
    t3 = threading.Thread(target=func2)
    t3.start()

if __name__ == '__main__':
    start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莎萌玩家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值