Python多线程基础知识

2024-03-29 00:29:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码:

import time
from threading import Thread

def fun1():
 time.sleep(5)

def fun2():
 time.sleep(5)

def fun3():
 time.sleep(5)

def fun4():
 time.sleep(5)

if __name__ == '__main__':
  t1 = Thread(target=fun1, args=())
  t2 = Thread(target=fun2, args=())
  t3 = Thread(target=fun3, args=())
  t4 = Thread(target=fun4, args=())
  t1.start()
  t2.start() 
  t3.start() 
  t4.start()
  start = time.clock()
  t1.join()
  t2.join()
  t3.join()
  t4.join()
  end = time.clock()
  print("Time Taken = ",end-start)

Que1:一次只为一个线程提供服务,这意味着如果控件使用线程t1,其他线程将等待。一旦上下文切换到线程t2,其余所有其他线程(t1、t3和t4)都将等待。 这是正确的理解吗?你知道吗

Que2:如果我对Que1的理解是正确的,那么总时间(开始-结束)应该是20秒(相当于以顺序方式而不是线程方式运行)……但是它有点接近5秒……为什么?在一天结束的时候,线程被一个接一个地按顺序(尽管不是全部)执行 请外行解释条款。在哪里我的理解有误吗?你知道吗

问题3:如果我用多重处理做同样的事情呢?执行会有什么不同?你知道吗

Que4:假设fun1()的代码对路由器1执行1000次重复计数ping,需要1分钟的时间。 类似地,fun2()对路由器2执行1000次重复计数ping,并花费1分钟的时间。 类似地,fun3()对路由器3执行1000次重复计数ping操作,需要1分钟的时间

如果我按顺序执行此操作,则的总预期时间为3分钟(ping到R1,然后ping到R2,然后ping到R3) 但是当我使用线程执行时,总的执行时间几乎接近1分钟。为什么?我无法理解。你知道吗


Tags: targettimedef时间argssleepping线程
3条回答

用于python中的多线程环境。我们有两种截然不同的TAK:

  • CPU限制:如添加数字,运行循环。。。任何消耗CPU的活动。这类任务占用GIL,因此它会阻止其他线程运行。你知道吗
  • 不受CPU限制(可能正在等待来自外部资源(如网络)的IO活动……):睡眠系统调用不使用CPU,因此属于这种类型。这种在等待IO时释放GIL,睡眠超时。。所以其他线程可以锁定并运行。 这就是为什么您的程序需要大约5秒钟,因为您的所有线程都可以并行运行。你知道吗

问题1:是的

问题2:如果每个线程的处理时间都是5秒,那么总时间应该是20秒。但是每个线程只休眠5秒,因此每个线程释放GIL,从而允许其他线程在等待休眠超时时“并行”运行(仅在概念上)。你知道吗

问题3:与threads不同,多处理创建的子进程可以在不同的处理器上同时运行(实际上是并行的)。但即使这些sleeps分别在不同的处理器上运行,它们仍将在大约5秒钟内全部完成。如果它们在同一个处理器上运行,操作系统的分时机制(类似于Python的线程机制)也将确保它们在大约5分钟内完成。你知道吗

问题4:这与sleep的概念相同。每个ping都不是CPU密集型的,因此它的线程很少拥有GIL。这允许所有三个ping线程在概念上并行运行。你知道吗

Python中的阻塞调用(sleep,等待I/O或锁)释放GIL,允许其他线程在被阻塞时运行,因此所有四个线程都可以sleep并行运行,这就是为什么您会看到5秒的延迟。如果你想看到GIL争用的效果,让线程函数做一些CPU限制的事情,例如

def fun():
    for _ in xrange(1000000000):
        pass

multiprocessing不会改变sleep情况的任何东西,因为您不是GIL绑定的,但是如果您有多个内核要运行,它会改善CPU绑定情况的挂钟时间。你知道吗

相关问题 更多 >