python 多线程

基本概念

线程和进程

进程:是计算机中的程序关于某数据集合上的一次运行活动,是系统资源分配和调度的基本单位,是操作系统的基本单位。
线程:有时被称为轻量级进程,是程序执行流的最小单元。一个标准的线程由线程ID,当前指针(pc),寄存器集合和堆栈组成。

并发解决模型

以下以火车站进站模型为例
1.队列,缓冲区
例子:火车站的乘客排队进站,排成的队就是一个缓冲区。军人,老幼病残优先,所以也有优先队列。
(queue模块的类queue,redis等)
2.争抢模式
谁抢到算谁的。同一时间只能进去一人,一个人进去,其余人不能进,等他进去后才能再进。
(锁机制:文件锁和线程锁)
3.预处理模式
在高峰时期多开几个通道,维持秩序。
(一种提前加载用户需求的数据思路,预处理思想,缓存常用)
4.并行模式
进站分为不同的进站口,每个进站口分为不同的队列,加速进站。
(可以通过购买服务器,多开进程,线程实现并行处理解决并发问题,水平扩展,分布式思想)
5.提速
多通道无法满足现阶段需求,进站不是问题,问题是如何传运如此多的人,把绿皮火车换为高铁,提高自身硬件条件。
(通过更新cpu,内存,硬盘等资源)
6.消息中间件
在进站前增加安检,在安检时就进行排队
(计算机中常见的消息中间件RabbitMQ,ActiveMQ(Apache),PocketMQ(Ali),Kafka(Apache)等)

线程生命周期

就绪:线程能够运行,但是在等待被调用,可能线程刚刚创建启动,或者刚刚从阻塞中恢复,或者被其他线程抢占。
运行:线程正在运行。
阻塞:线程等待外部时间发生而且无法运行,如I/O操作。
终止:线程完成,或推迟,或被取消。

Thead类

签名

def init(self,group=None,target=None,name=None,args=(),kwargs=None,deamon=None)
target:线程的对象,就是目标函数
name:为线程起名字
args:为目标函数传递实参,元组
kwargs:为目标函数关键字传参,字典

Thead 线程和主线程的关系

守护线程

如果不设置deamon,就取当前线程的deamon来设置它。
主线程为non-deamon线程,即deamon=False
从主线程创建的所有线程不设置deamon属性,则默认都是deamon=False,也就是None=deammon线程。
线程中只要有:None=deamon线程时就无法退出。

线程属性

模块属性

在这里插入图片描述

线程属性

在这里插入图片描述
以小红车小蓝车过红绿灯为例

import time
import threading
llight = {}
def linght(sconds):
    count = 5
    llight[threading.current_thread().name]="ret"
    while True:
        name = threading.current_thread().name
        print("{} is {} now!,senconds is {}".format(name,llight[threading.current_thread().name],count))
        count -= 1
        if count == 0 and llight[threading.current_thread().name] == "ret":
            llight[threading.current_thread().name] = "blue"
            count = 5
        if count == 0 and llight[threading.current_thread().name] == "blue":
            llight[threading.current_thread().name] = "ret"
            count = 5
        time.sleep(sconds)

def car(s):
    for k,v in llight.items():
        if v == "ret":
            count = 0
            while True:
                time.sleep(0.5)
                count += 0.5
                if llight[k] != "ret":
                    print("ret to blue,car pass")
                    break
                if count > s:
                    print("ret ret go go go!")
                    break
        else:
            print("blue light pass".format(k))



lt = threading.Thread(target=linght,args=(2,),name="light1").start()
lt1 = threading.Thread(target=linght,args=(4,),name="light2").start()
ct = threading.Thread(target=car,args=(6,)).start()

线程同步

线程同步Event

Event事件,是线程间通信机制中最简单的实现,使用一个内部标记flag,通过flag的true或false的变化进行操作。
在这里插入图片描述
event = threading.Event()
print(“ready”)
print(event.wait(4))#默认false,执行wait时长为4s,函数返回值
print(“done”)

线程同步Lock,Rlock

锁,凡是存在共享资源争抢的地方都可以使用锁,从而保证只有一个使用者可以完成使用一个资源。
Lock:锁,一旦线程获得锁,其他线程试图获取锁的线程将被阻塞
在这里插入图片描述
可重复锁rlock,在一个线程中,可以锁多次,锁多次时,就要对于的解锁多次,否则其他阻塞锁中,无法执行任务

线程不同:condition

构造方法Condition(lock=None),可以传入一个lock或Rlock对象,默认是Rlock

在这里插入图片描述
Conddition用于生产者、消费者模型,为了解决生产者和消费者速度不匹配的问题。
使用方式:
使用Condition,必须先acquire,用完了要release,因为内部使用了锁,默认使用了Rlock锁,最好使用方式是with上下文。
消费者wait,等待通知。
生产者生产好消息,对消费者发通知,可以使用notify或者notify_all方法
通知案例:

cond = threading.Condition()
env = threading.Event()
data = 0
def produce(total):
    for _ in range(total):
        global data
        data = random.randint(0,100)
        with cond:
            print(data)
            cond.notify_notify(n=2)
        env.wait(1)
    env.set()
def consume():
    global  data
    while not env.is_set():
        with cond:
            cond.wait()  #阻塞等通知
            print("received {}".format(data))
            data = None
        env.wait(0.5)
p = threading.Thread(target=produce,args=(10,),name="producer")
for con in range(5):
    con = threading.Thread(target=consume,name=“consumer”)         #5个消费者,等待处理,现在最多通知5个,一对多广播
    con.start()
p.start()

进程池

multiprocess.Pool是进程池类

import multiprocessing
import datetime
start = datetime.datetime.now()
def calc(i):
    sum = 0
    for _ in range(1000000000):
        sum += 1
    print(i,sum)
    return sum
A = []
if __name__ == "__main__":
    start = datetime.datetime.now()
    pool = multiprocessing.Pool(5)
    for i in range(5):
        #回调函数必须接受一个参数
        pool.apply_async(calc,args=(i,),callback=lambda x:A.extend(x))
    pool.close()
    pool.join()
    delta = (datetime.datetime.now() -start).total_seconds()
    print(delta)
    print(A)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python的多线程可以使用内置的`threading`模块来实现。这个模块提供了一些对象和方法,可以方便地创建和管理线程。 以下是一个简单的多线程示例,它创建了两个线程,每个线程都打印数字1到5: ```python import threading def print_numbers(): for i in range(1, 6): print(threading.current_thread().name, i) # 创建两个线程 t1 = threading.Thread(target=print_numbers) t2 = threading.Thread(target=print_numbers) # 启动线程 t1.start() t2.start() # 等待线程结束 t1.join() t2.join() print("All threads have finished.") ``` 在这个示例中,我们首先定义了一个`print_numbers()`函数,它用于打印数字1到5,并且在每个数字前面打印线程的名称。然后,我们创建了两个线程`t1`和`t2`,它们都指向`print_numbers()`函数。接下来,我们启动这两个线程,并等待它们完成,最后输出"All threads have finished."。 注意,`threading.current_thread().name`用于获取当前线程的名称。在这个示例中,我们没有指定线程的名称,因此它们将默认为"Thread-1"和"Thread-2"。 多线程可以提高程序的执行效率,但是也需要注意线程安全问题,比如并发访问共享变量可能会导致数据不一致的问题。因此,在编写多线程程序时,需要特别注意线程安全问题。 ### 回答2: Python线程是指在一个程序中同时执行多个线程,每个线程都可以独立执行不同的任务。Python的多线程是基于线程模块实现的,通过创建多个线程对象来实现多线程的功能。 Python线程的使用需要导入threading模块,使用threading.Thread类来创建线程对象。通过调用线程对象的start()方法,线程就会开始执行。线程可以是执行同一个函数,也可以是执行不同的函数,甚至可以是执行不同的类的方法。 线程之间可以共享全局变量,但需要避免多个线程同时修改全局变量的情况,可以通过互斥锁机制来保证数据的一致性。 Python线程的优点是能够提高程序的执行效率,特别是在IO操作较多的情况下,多线程可以充分利用CPU的空闲时间。另外,多线程还可以实现一些并发的功能,例如同时下载多个文件、同时处理多个网络请求等。 然而,Python的多线程在处理CPU密集型任务上并不适用,因为在Python中,多线程并不能利用多核CPU的优势,由于Python的GIL(全局解释器锁)机制,多线程在CPU密集型任务上的效率并不比单线程高。 总结来说,Python的多线程适用于IO密集型任务,能够提高程序的执行效率和实现并发的功能,但对于CPU密集型任务,单线程可能更适合。 ### 回答3: Python线程是指在一个程序中同时运行多个线程,每个线程独立执行其任务。Python 中的多线程可以通过使用 threading 模块来实现。 在 Python 中,多线程的主要优势是能够提升程序的执行效率。通过多线程,可以将耗时较长的任务分配给不同的线程来并行执行,从而缩短程序的总执行时间。这尤其适用于那些需要频繁进行网络请求、IO 操作或者计算密集型任务的程序。 使用 Python 的 threading 模块可以很方便地创建和管理线程。通过创建 Thread 对象并传入要执行的函数,就可以创建一个新的线程。可以使用 start() 方法来启动线程,并使用 join() 方法来等待线程执行完成。 需要注意的是,Python 中的多线程并不能真正实现并行执行,而是通过在不同任务之间快速切换来模拟并行。这是由于 Python 的全局解释器锁(GIL)的存在,它使得同一时间只有一个线程能够执行 Python 的字节码。因此,在计算密集型任务上,使用多线程并不能获得真正的并行加速。 另外,多线程在处理共享资源时需要注意线程安全问题。多个线程同时访问和修改共享数据可能会导致数据不一致或者竞争条件。在这种情况下,可以通过使用锁(Lock)等同步机制来确保数据的正确访问和更新。 总而言之,Python线程可以提升程序的执行效率,适用于需要进行网络请求、IO 操作或者并发处理的任务。然而,在计算密集型任务上,并不能实现真正的并行加速。同时,在处理共享资源时需要注意线程安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值