簡體   English   中英

使用2個線程計算Python中的第n個素數

[英]Use 2 Threads to calculate the nth prime number in Python

我正在嘗試使用 Python 制作一個素數計算器。 我設法編寫了一個順序版本,但我必須使其並行。

要求:

  1. 素數必須由函數重新計算,而不是在某處查找。

  2. 必須有 2 個線程參與計算

  3. 程序應該盡可能快


現在我的代碼是:

import sys
import math 
import cProfile

def is_prime(num):
    for j in range(2,int(math.sqrt(num)+1)):
        if (num % j) == 0:
            return False
    return True

def prime(nth):
    """Return the nth prime number.
    >>> prime(3)
    The 3th prime number is: 5
    >>> prime(4)
    The 4th prime number is: 7
    >>> prime(1000)
    The 1000th prime number is: 7919
    """
    i = 0
    num = 2

    while i < nth:
        if is_prime(num): 
            i += 1
            if i == nth:
                print('The ' + str(nth) + 'th prime number is: ' + str(num))
        num += 1

if __name__ == "__main__":
    import doctest
    doctest.testmod()
    cProfile.run('print(prime(1000))')

這是我目前的答案,

import threading, doctest, cProfile, time, random
result = [2]
counter = 1

def get_int(num):
    for i in range(3, num):
        yield i

def is_prime(num):
    for j in range(2,int(num)):
        if (num % j) == 0:
            return False
    result.append(num)
    return True 

def prime_calculator(nth):
    lock = threading.Lock()
    global result, counter, integer
    while counter < (nth):
        if is_prime(next(integer)):
            lock.acquire()
            try:
                counter += 1
            finally:
                lock.release()
        time.sleep(random.random()/1000)

def prime(nth):
    """Returns the nth prime number
    >>> prime(1)
    2
    >>> prime(2)
    3
    >>> prime(4)
    7
    >>> prime(1000)
    7919
    """   
    global integer, counter, result
    integer = get_int(99999999)
    threads = [threading.Thread(daemon=True, target=prime_calculator, args=(nth,)) for i in range(2)]
    [thread.start() for thread in threads]
    [thread.join() for thread in threads]
    counter = 1
    return result[-1]

if __name__ == "__main__":
    doctest.testmod()
    cProfile.run('print(prime(1000))')

但是它不是線程安全的,因為它使用了一個計數器,稍后將嘗試在沒有計數器的情況下做一個。

import threading
import time

results=[]
primelock=False

def partisprime(num,start,end):
    global results
    for n in range(start,end,2):   
        if num%n==0:
            results.append(False)
            return
    results.append(True)

def isprime(num,threads=4):
    global primelock
    if primelock:
        raise Exception("isprime is already running")
    primelock=True
    if num==2 or num==3:
        return True
    if num%2==0 or num<2:
        return False
    tavoite=int(num**0.5)+1
    valitav=(tavoite+threads-1) // threads
    global results
    results=[]
    mythreadlist=[]
    for t in range(0,threads,1):
        if t == 0:
            mythreadlist.append(threading.Thread(target=partisprime,args=(num,3,valitav)))
            mythreadlist[len(mythreadlist)-1].start()
        else:
            starttis=valitav*t
            if starttis % 2 == 0:
                starttis+=1
            mythreadlist.append(threading.Thread(target=partisprime,args=(num,starttis,valitav*(t+1))))
            mythreadlist[len(mythreadlist)-1].start()
    breakthis=False
    while len(results) < threads:
        for i in range(len(results)):
            if results[i] == False:
                breakthis=True
                break
        if breakthis:
            break
        time.sleep(0.01)
    if breakthis:
        for i in range(len(mythreadlist)):
            mythreadlist[i].stop()
        primelock=False
        return False
    output=True
    for i in range(len(results)):
        output=output and results[i]
    primelock=False
    return output

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM