2016-07-10 5 views
0

私は通常インターネット上で質問をしませんし、プログラマーもいいですが、この問題にしばらくは苦労していますが、なぜうまくいかないのか分かりません。私は、複数のスレッドでできると思った数学をやろうとしています。下のコードは、各ワーカーが終わったときに出てくる回答を出力しようとしています。私はすでにそれがかなり非効率的であることを認識しています。それは、労働者が他人や確かに他の多くの問題を待たなければならないものですが、私はこのバージョンを稼働させたいだけです。大幅プログラム全体を出力するPythonマルチプロセッシング

を高く評価され、私はここで4つのコアと8つのスレッドとコンソールを介してプログラムを実行し、

で、窓10、のpython 3.5を実行していますすべてのヘルプは私のコードです:

import math 
from multiprocessing import Process, Lock 
import time 

lowMult = 0 
highMult = 0 
dist = "ERROR!" 
print("Welcome to this maths test program") 
print("We will be testing the nature of closest whole multiple pairs") 
print("this test will run for all values 900000 to 900100") 
print("press enter to begin") 
input() 

def worker(name, l, num): 
    l.acquire() 
    print (name, "Starting") 
    l.release() 
    found = False 
    test = math.sqrt(num) 
    if (test % 1) == 0: 
     l.acquire() 
     print(num, "=", int(test), "*", int(test), "0", "SQRT!") 
     l.release() 

    else: 
     test = int(test) 
     for lowMult in range(test, 0, -1): 
       for highMult in range(test, (num +1)): 
        if (lowMult * highMult) == num: 
         found = True 
         dist = highMult - lowMult 
         break 

       if found: 
        break 

     l.acquire() 
     if lowMult == 1: 
      print(num, "=", lowMult, "*", highMult, dist, "PRIME!") 
     else: 
      print(num, "=", lowMult, "*", highMult, dist) 

     print (name, "Exiting") 
     l.release() 

if __name__ == '__main__': 
    lock = Lock() 
    jobs = [] 
    num0 = 900000 
    num1 = 900001 
    num2 = 900002 
    num3 = 900003 
    for num in range(1, 100): 
     thread1 = Process(name='worker 1', target=worker, args=("worker 1", lock, num0,)) 
     jobs.append(thread1) 
     thread1.start() 

     thread2 = Process(name='worker 2', target=worker, args=("worker 2", lock, num1,)) 
     jobs.append(thread2) 
     thread2.start() 

     thread3 = Process(name='worker 3', target=worker, args=("worker 3", lock, num2,)) 
     jobs.append(thread3) 
     thread3.start() 

     thread4 = Process(name='worker 4', target=worker, args=("worker 4", lock, num3,)) 
     jobs.append(thread4) 
     thread4.start() 

     thread1.join() 
     thread2.join() 
     thread3.join() 
     thread4.join() 

     num0 += 4 
     num1 += 4 
     num2 += 4 
     num3 += 4 

     while True: 
      if thread1.is_alive() & thread2.is_alive() & thread3.is_alive() & thread4.is_alive(): 
       time.sleep(2) 
      else: 
       input() 
       break 

中のIDLE私は何を取得、しかし、私はこれが起こるだろうと周りの読みが、コンソールに、私は最初の数の印刷は、私は複数回を期待しています何の代わりにコマンドを取得する:

print("Welcome to this maths test program") 
print("We will be testing the nature of closest whole multiple pairs") 
print("this test will run for all values 900000 to 900100") 
print("press enter to begin") 

私はFを取得します我々の最初の計算が完了したが、それは並行していないと思われ、第2の入力プロンプトが終わることはない。私のCPU使用量から、それは決して始まると思われますが、プログラムは終了しません。私は何が起こっているのか分かりません。

EDIT:

実際のコンピューティングの問題は、私のinput()の使用と「名前」の定義の範囲内にあるかのように思えます。 .join()の他のいくつかの問題でそれらが削除され、.is_alive()チェックがANDの代わりにORを使うように修正されました。私のpython 3.5でこのコードを実行すると、私はWindowsコンソールを取得する際にもかかわらず、私が意図せずにこのコードの4つのコピーを取得:

Welcome to this maths test program 
We will be testing the nature of closest whole multiple pairs 
this test will run for all values 900000 to 900100 
press enter to begin 

これは私が現在解決しようとしていますものです。

+0

あなたは「それはクラッシュ」何を意味するのに十分なレベルに達した後、私は他の人を支援することができ、一日を願って、非常に患者と参考にされていますか? –

+0

私はトレースバックを取得、名前は定義されていませんが、私はこれが接続されていないと信じています。意図された結果は、労働者に数字とその要因を印刷させることであった。これには平方根があるか、素数であるかも含まれる。代わりに、最初の4行の導入テキストが繰り返されますが、これは従業員コードの一部ではありません。 –

答えて

0

それはマニュアルに従って「eval(raw_input(prompt))と同等」であるので、あなたは、Pythonの2.7、そしてinput()うそう「クラッシュ」を使用している場合: https://docs.python.org/2/library/functions.html#input

あなたは(ユーザー入力を読み取るために、raw_inputを使用することができます実際には私はここでキーを押すよう求めているところはない)。

もう1つの問題は、変数nameworker関数で定義されていないことです。

thread1.is_alive() & thread2.is_alive() & thread3.is_alive() & thread4.is_alive()も常にFalseと評価されます。私は理解して期待された結果であると考えられるすべてのinput()を除去した後、私が手出力は(Pythonの2.7で)で、次の

、:

Welcome to this maths test program 
We will be testing the nature of closest whole multiple pairs 
this test will run for all values 900000 to 900100 
press enter to begin 
(900000, 'Starting') 
(900001, 'Starting') 
(900002, 'Starting') 
(900003, 'Starting') 
(900000, '=', 900, '*', 1000, 100) 
('worker 1', 'Exiting') 
(900003, '=', 611, '*', 1473, 862) 
('worker 4', 'Exiting') 
(900002, '=', 2, '*', 450001, 449999) 
('worker 3', 'Exiting') 
(900001, '=', 1, '*', 900001, 900000, 'PRIME!') 
('worker 2', 'Exiting') 
(900004, 'Starting') 
(900005, 'Starting') 
(900006, 'Starting') 
(900007, 'Starting') 
(900006, '=', 6, '*', 150001, 149995) 
('worker 3', 'Exiting') 
(900004, '=', 28, '*', 32143, 32115) 
('worker 1', 'Exiting') 
(900007, '=', 1, '*', 900007, 900006, 'PRIME!') 
('worker 4', 'Exiting') 
(900005, '=', 5, '*', 180001, 179996) 
('worker 2', 'Exiting') 
... 
+0

私は今、 '名前'がエラーを引き起こしている可能性があると認識していますが、元の問題を解決しません。 –

+0

また、私はpython 3.5を使用していますので、入力は悲しいことではありません。それは簡単だったでしょう。 –

+0

@TomassWilsonたぶんあなたはキーボードを押すのを忘れました(一番内側のループにinput()があるので)?あなたの質問を正しく理解すれば、私が得られる出力は期待されるものと思われます。 – FJDU

0

最初のワーカーがされていないため、nameにクラッシュしますを保持している間にと定義されています。それは、他の労働者のいずれかが産出するのを妨げ、彼らは決して終わらないので、次の労働者の出発からの主要なプロセスも停止する。

この問題を回避するには(大きな設計上の問題ではなく)、acquirereleaseを明示的に呼び出すのではなく、コンテキストマネージャーとしてロックを使用する必要があります。

with l: 
    print(num, "=", int(test), "*", int(test), "0", "SQRT!") 

そして:

with l: 
    if lowMult == 1: 
     print(num, "=", lowMult, "*", highMult, dist, "PRIME!") 
    else: 
     print(num, "=", lowMult, "*", highMult, dist) 

    print (name, "Exiting") # this still causes an exception, but it will no longer deadlock! 
0

を私の質問のほとんどが回答されているかのように思えこれは、例外が発生するたびに自動的にロックを解除できるようになります。元の問題が解決されたので、実際にコードを効率的に最適化して効率的に実行するように作業します。従業員が親プログラムのすべてのコードを実行し始めているようで、導入テキストを4回以上印刷しないようにするために、インプリントの前にif __name__ == __main__:を含めました。また、input()が問題の原因となった原因についても説明します。明らかに、私が抱えていた問題の中心は、自分が指定された機能のコードを実行したという印象を受けていたので、労働者の仕組みに関する知識が不足していることです。回答したすべての

おかげで、私は唯一の私のスキルが

関連する問題