2017-11-14 15 views
0

this questionのフォローアップとして、私はjsonファイルで読むthreadpoolexecutorを開始する簡単なスクリプトを持っています。それをやりながら、forループを使用して1から9までカウントします。私がexecutor.shutdown(wait=False)を使用したにもかかわらず何らかの理由でそれはまだブロックし、read_employeesメソッドが実行されるのを待ちます。 documentationによるとBlockPoolExecutorをブロッキングなしで使用する

待ち時間がFalseの場合、このメソッドはすぐに返され、保留中のすべての先物が

import concurrent.futures 
import json 
import time 


def read_employees(read_file): 
    with open(read_file) as f_obj: 
     employees = json.load(f_obj) 

    for emp in employees: 
     print(emp) 
     time.sleep(3) 


def start_thread(): 
    filename = 'employee.json' 
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: 
     executor.submit(read_employees, filename) 
     executor.shutdown(wait=False) 

def print_number(): 
    for num in range(1,10): 
     time.sleep(2) 
     print(num) 


start_thread() 
print_number() 
を実行して行われたときに、エグゼキュータに関連付けられたリソースが解放されます

私がこれを行う場合:

def read_employees(read_file): 
    with open(read_file) as f_obj: 
     employees = json.load(f_obj) 

    for emp in employees: 
     time.sleep(5) 
     print(emp) 


def print_number(): 
    for num in range(1,10): 
     print(num) 


filename = 'employee.json' 
empThread = threading.Thread(target=read_employees, args=(filename,)) 
empThread.start() 

print_number() 

最初に1から9までカウントしてから従業員をプリントアウトしますが、その遅れは従業員を読​​みながら就寝しているためです。これと同じように:

1 
2 
3 
4 
5 
6 
7 
8 
9 
[email protected] 
[email protected] 

どのように私はブロックせずにthreadpoolexecutorを使用して同じ出力を達成していますか?

答えて

0

この小さなスニペットにおそらく起因する:

は、「あなたはwith文を、使用している場合、明示的に、このメソッドを呼び出すことを避けることができますシャットダウンExecutor(待っTrueからwaitセットで呼び出されたExecutor.shutdown()かのように) 「

https://docs.python.org/3/library/concurrent.futures.html

+0

私はは 'false'に' wait'を設定する理由ですが、それがブロックしているかのよう、それはまだ出力:

2番目のオプションは、このような何かを行うことです。 –

1

私はあなたがwithステートメントを使用しないことをお勧めします。 withステートメントはcontext manager__exit__メソッドを呼び出すことによって終了します。コンテキストマネージャは、__enter__および__exit__メソッドを実装する任意のクラスです。したがって、すべてがwithステートメント内で実行された後、渡されたコンテキストマネージャーで__exit__が呼び出されます。

この場合、ThreadPoolExecutorはコンテキストマネージャです。 ThreadPoolExecutorExecutorのサブクラスです。したがって、Executor's class definitionを参照すると、その__exit__メソッドではself.shutdown(wait=True)が呼び出されます。

self.shutdown(wait=True)への呼び出しが問題です。コンテキストマネージャの仕組みに従えば、withステートメントの最後のものはself.shutdown(wait=False)なので、__exit__は直後に呼び出されます。つまり、self.shutdown(wait=True)が呼び出されます。それがあなたをブロックしているのです。

これを解決する方法は2つあります。最初はThreadPoolExecutorをサブクラス化し、__exit__メソッドを書き直すことです。

def start_thread(): 
    filename = 'employee.json' 
    executor = concurrent.futures.ThreadPoolExecutor(max_workers=2) 
    executor.submit(read_employees, filename) 
    executor.shutdown(wait=False) 
関連する問題