【问题标题】:Calculate factorials with threads in Python在 Python 中使用线程计算阶乘
【发布时间】:2020-11-26 16:13:18
【问题描述】:

我必须测试 n = 17 是否为质数:(n-1)!模 n = n-1。首先,我必须计算 16 到 4 个线程的阶乘,这意味着间隔 1..16 必须分成 4 个子间隔:1..4、5..8、9..12、14 ..16。我已经设法通过 16 个线程测试了 17 是否是质数,每个操作一个,但我不知道如何细分它以便仅在 4 个线程中完成操作。

非常感谢您的一些想法,谢谢!

这是我的代码:

import threading

n = 17
t = n-1
ts = []
num = (n-1)/t
       
def calcFak():
    for i in range(t):
        c = i*(n-1)/t+1
        thread = threading.Thread(target=threads, args = (c,))
        ts.append(thread)
        thread.start()
        thread.join()
        

def threads(var):
    print(f"start thread {var}")
    global num
    num = num * var
    print(f"end thread {var}")

def managerThread(thread):
    calcFak()
    print(num)
    if num % n == t:
         print(n, ' is Prime')
    else:
         print(n, ' is not Prime')
    
    
t2 = threading.Thread(target = managerThread, args=(ts,))
t2.start()

【问题讨论】:

  • 子间隔都在自己的线程中是否重要?我觉得有 16 个任务并让它们由 4 个线程执行会更有效率。
  • 嗨 Finn,感谢您的回复。在这种情况下,每个子间隔都必须有自己的线程。这是一个在 Python 中练习同步的练习,所以我不确定它是否有望高效
  • 你不应该期望能够在纯 Python 代码中进行并行计算:realpython.com/python-gil
  • 出于好奇,你为什么要实现这个特定的算法?有一些方法可以在不显式计算 (N-1) 的情况下测试 N 是否为素数!
  • 您好所罗门,谢谢您的回答。这是一个练习与 Python 同步的练习,我按照提供的说明进行操作,其中一个是测试 n 是否为素数的方式

标签: python python-3.x multithreading python-2.7 factorial


【解决方案1】:

由于calcFak() 函数中的线程join() 语句,现在您正在按顺序计算所有内容。因此,现在你的函数的执行实际上和下面的代码是一样的:

n = 17
t = n - 1
num = t/t

for i in range(t):
    c = i*t/t + 1
    print(f'Start {c}')
    num = num * c
    print(f'End thread {c}')

print(num)
if num % n == t:
    print(f'{n} is a prime number')
else:
    print(f'{n} is not a prime number')

如您所见,没有线程优势。相反,使用queues 和工作函数来细分程序的执行:

import threading
from queue import Queue
import time
n = 17
t = n - 1
num = t/t

# For threading
q = Queue()
num_lock = threading.Lock() # Lock so that no threads can overwrite our num value
threads = []                # List to store created threads

# Our worker gets items from the queue and processes them
def worker():
    global num
    while True:
        if not q.empty():
            c = q.get()
            num_lock.acquire()
            num = num * c
            num_lock.release()
            q.task_done()

for i in range(t):
    q.put(i*t/t + 1)

for thread in range(4):
    threads.append(threading.Thread(target=worker))
    threads[-1].daemon = True
    threads[-1].start()
    print('Made 1 thread')

q.join()

if num % n == t:
    print(f'{n} is a prime number')
else:
    print(f'{n} is not a prime number')

# Prints:
# Made 1 thread
# Made 1 thread
# Made 1 thread
# Made 1 thread
# 17 is a prime number

在上面的代码中,我们创建了一个队列来保存供工作函数使用的数据。工作函数获得num 变量的锁定,然后对其进行修改。一旦队列为空(这发生在我们使用q.join() 加入队列之后),我们就访问num 变量的最终值以确定该数字是否为素数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 2011-03-06
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多