当前位置: 首页 > 知识库问答 >
问题:

多线程与单线程计算

戈博易
2023-03-14
def dowork():
  y = []
  z = []
  ab = 0
  start_time = time.time()
  t = threading.current_thread()

  for x in range(0,1500):
    y.append(random.randint(0,100000))
  for x in range(0,1500):
    z.append(random.randint(0,1000))
  for x in range(0,100):
    for k in range(0,len(z)):
      ab += y[k] ** z[k]
  print(" %.50s..." % ab)
  print("--- %.6s seconds --- %s" % (time.time() - start_time, t.name))

#do the work!
threads = []
for x in range(0,4): #4 threads
  threads.append(threading.Thread(target=dowork))

for x in threads:
  x.start() # and they are off
 23949968699026357507152486869104218631097704347109...
--- 11.899 seconds --- Thread-2
 10632599432628604090664113776561125984322566079319...
--- 11.924 seconds --- Thread-4
 20488842520966388603734530904324501550532057464424...
--- 12.073 seconds --- Thread-1
 17247910051860808132548857670360685101748752056479...
--- 12.115 seconds --- Thread-3
[Finished in 12.2s]
def dowork():
  y = []
  z = []
  ab = 0
  start_time = time.time()
  t = threading.current_thread()

  for x in range(0,1500):
    y.append(random.randint(0,100000))
  for x in range(0,1500):
    z.append(random.randint(0,1000))
  for x in range(0,100):
    for k in range(0,len(z)):
      ab += y[k] ** z[k]
  print(" %.50s..." % ab)
  print("--- %.6s seconds --- %s" % (time.time() - start_time, t.name))

# print(threadtest())
threads = []
for x in range(0,4):
  threads.append(True)

for x in threads:
  dowork()
 14283744921265630410246013584722456869128720814937...
--- 2.8463 seconds --- MainThread
 13487957813644386002497605118558198407322675045349...
--- 2.7690 seconds --- MainThread
 15058500261169362071147461573764693796710045625582...
--- 2.7372 seconds --- MainThread
 77481355564746169357229771752308217188584725215300...
--- 2.7168 seconds --- MainThread
[Finished in 11.1s]

为什么单线程和多线程脚本具有相同的处理时间?多线程实现不是应该少1/#线程数吗?(我知道当您达到最大cpu线程时,回报会递减)

我搞砸了我的实现吗?

共有1个答案

夏祺然
2023-03-14

Python中的多线程不像其他语言那样工作,如果我没记错的话,它与全局解释器锁有关。但是有很多不同的变通方法,例如,您可以使用GEvent的基于coroutine的“线程”。对于需要同时运行的工作,我本人更喜欢dask。例如

import dask.bag as db
start = time.time()
(db.from_sequence(range(4), npartitions=4)
     .map(lambda _: dowork())
    .compute())
print('total time: {} seconds'.format(time.time() - start))

start = time.time()
threads = []
for x in range(0,4):
  threads.append(True)

for x in threads:
  dowork()
print('total time: {} seconds'.format(time.time() - start))

和输出

 19016975777667561989667836343447216065093401859905...
--- 2.4172 seconds --- MainThread
 32883203981076692018141849036349126447899294175228...
--- 2.4685 seconds --- MainThread
 34450410116136243300565747102093690912732970152596...
--- 2.4901 seconds --- MainThread
 50964938446237359434550325092232546411362261338846...
--- 2.5317 seconds --- MainThread
total time: 2.5557193756103516 seconds
 10380860937556820815021239635380958917582122217407...
--- 2.3711 seconds --- MainThread
 13309313630078624428079401365574221411759423165825...
--- 2.2861 seconds --- MainThread
 27410752090906837219181398184615017013303570495018...
--- 2.2853 seconds --- MainThread
 73007436394172372391733482331910124459395132986470...
--- 2.3136 seconds --- MainThread
total time: 9.256525993347168 seconds

在本例中,dask使用multiprocessing来完成这项工作,对于您的情况来说,这可能是需要的,也可能是不需要的。

 类似资料:
  • 问题内容: 我想看看使用多线程生产者而不是单线程生产者会有多少时间差异。我在本地计算机上设置了ActiveMQ,编写了生产者类,该类将初始化并在其构造函数中启动JMS连接。我将消息限制设置为3M,将所有消息推送到ActiveMQ大约花费了50秒。我只发送了一个字符串“ hello world” 3M次。 然后,我使用了相同的生产者对象(一个连接但有多个会话),并使用线程大小为8的ExecutorS

  • 问题内容: 我想检查多线程是否比单线程快,然后在这里进行演示: 首先我用两个sum方法运行singleThreadStart,结果是 然后我运行secondThreadStart,结果是 然后我用五和方法运行singleThreadStart,结果是 最后我运行FiveThreadStart,结果是 我的问题是: SecondThreadStart比singleThreadStart花费更多的时间

  • 我想检查多线程是否比单线程快,然后我在这里做一个演示: 首先,我用二和方法运行singleThreadStart,结果是 然后我运行第二个ThreadStart,结果是 然后我用五和方法运行singleThreadStart,结果是 最后我运行fiveThreadStart,结果是 我的问题是: SecondThreadStart比singleThreadStart花费更多的时间,是因为创建线程的

  • 问题内容: Python中的和模块之间有什么区别? 问题答案: 在Python 3中,已重命名为。它是用于实现的基础结构代码,普通的Python代码不应该靠近它。 公开了底层操作系统级别流程的原始视图。这几乎绝不是您想要的,因此在Py3k中重命名以表明它实际上只是实现细节。 添加了一些额外的自动记帐功能,以及一些便捷实用程序,所有这些使它成为标准Python代码的首选。

  • 问题内容: 我从一个非常简单的多线程示例开始。我试图做一个线程安全的计数器。我想创建两个线程,使计数器间歇地增加到1000。以下代码: 据我所知,while循环现在意味着只有第一个线程才能访问计数器,直到达到1000。输出: 我该如何解决?如何获得共享计数器的线程? 问题答案: 两个线程都可以访问您的变量。 您看到的现象称为线程饥饿。输入代码的受保护部分后(很抱歉,我之前错过了它),其他线程将需要

  • 问题内容: 我编写了一个单一的Kafka使用者(使用Spring Kafka),该使用者从单个主题中读取内容,并且是使用者组的一部分。消耗完一条消息后,它将执行所有下游操作,并移至下一个消息偏移。我将其打包为WAR文件,并且我的部署管道将其推送到单个实例。使用部署管道,我可以将该工件部署到部署池中的多个实例。 但是,当我希望多个消费者作为基础架构的一部分时,我无法理解以下内容: 实际上,我可以在部