1

リスト内に新しいジョブを作成するマルチプロセッサ システムを機能させるにはどうすればよいですか? 私は得続けます:

self._popen が None であることをアサートします。「プロセスを 2 回開始することはできません」

私は基本的に同じジョブの複数のインスタンスを作成しているので、これは理にかなっています...どうすれば修正できますか? マルチプロセッサ プールをセットアップする必要がありますか?

もっと明確にする必要がある場合はお知らせください。

ここに私のマルチプロセッシングクラスがあります:

class Worker(multiprocessing.Process):

    def __init__(self, output_path, source, file_name):
        self.output_path = output_path
        self.source = source
        self.file_name = file_name

    def run(self):

        t = HTML(self.source)
        output = open(self.output_path+self.file_name+'.html','w')
        word_out = open(self.output_path+self.file_name+'.txt','w')  
        try:
            output.write(t.tokenized)

            for w in word_list:
                if w:
                    word_out.write(w+'\n')

            word_out.close()
            output.close()
            word_list = []

        except IndexError: 
            output.write(s[1])
            output.close()
            word_out.close()

        except UnboundLocalError:
            output.write(s[1])
            output.close()
            word_out.close()   

これは、このすべてを実装するクラスです。

class implement(HTML):

    def __init__(self, input_path, output_path):
        self.input_path = input_path
        self.output_path = output_path

    def ensure_dir(self, directory):
        if not os.path.exists(directory):
            os.makedirs(directory)
        return directory    

    def prosses_epubs(self):
        for root, dirs, files in os.walk(self.input_path+"\\"):
            epubs = [root+file for file in files if file.endswith('.epub')]
            output_file = [self.ensure_dir(self.output_path+"\\"+os.path.splitext(os.path.basename(e))[0]+'_output\\') for e in epubs]

        count = 0 
        for e in epubs:
            epub = epubLoader(e)

            jobs = []

            # this is what's breaking everything right here. I'm not sure how to fix it. 
            for output_epub in epub.get_html_from_epub():                
                worker = Worker(output_file[count], output_epub[1], output_epub[0])
                jobs.append(worker)
                worker.start()

            for j in jobs:
                j.join()

            count += 1
        print "done!"


if __name__ == '__main__':
    test = implement('some local directory', 'some local directory')    
    test.prosses_epubs()

これに関する助けをいただければ幸いです。また、自分のコードで行っていることをもっとうまくできるかどうかも教えてください... 私は常に最善の方法で物事を行う方法を学ぼうとしています。

4

1 に答える 1

3
  • 関数で十分な場合は、クラスを使用しないでください。この場合、各クラスには本質的に 1 つの肉付きの良いメソッドがあり、__init__メソッドは肉付きのメソッドで使用される引数を保持しているだけです。肉付きの良いメソッドを関数にして、引数を直接渡すだけで、コードをより洗練されたものにすることができます。
  • 「ジョブ」(つまりタスク) の概念を「ワーカー」(つまりプロセス) の概念から分離します。マシンのプロセッサの数は限られていますが、ジョブの数ははるかに多くなる可能性があります。CPU を圧倒する可能性があるため、ジョブごとに新しいプロセスを開きたくありません。
  • withこのステートメントを使用して、ファイル ハンドルが確実に閉じられるようにします。私はそれぞれ3つの異なる場所で見たり呼ばれたりしていますoutput.close()word_out.close()Python が-suitewithを離れると、これらのファイル ハンドルは自動的に閉じられますwith
  • multiprocessing Poolはあなたのコードでうまくいくと思います。を使用して、プール内のワーカーにジョブを送信できますpool.apply_async。各呼び出しは、プール内のワーカーが処理できるようになるまで待機するジョブをキューに入れます。pool.join() すべてのジョブが完了するまでメインプロセスを待機させます。
  • os.path.joinでディレクトリを結合する代わりに使用し'\\'ます。これにより、コードが Windows 以外のマシンと互換性を持つようになります。
  • カウンターを手動で実装/インクリメントする代わりに列挙を使用します。入力が少なくなり、コードが少し読みやすくなります。

epubLoaderHTML、およびが定義されていないため、次のコードは実行さword_listれませんが、上記で私が提案していることをより明確に理解できるかもしれません。

import multiprocessing as mp

def worker(output_path, source, filename):
    t = HTML(source)
    output_path = output_path+filename
    output = open(output_path+'.html', 'w')
    word_out = open(output_path+'.txt','w')
    with output, word_out:
        try:
            output.write(t.tokenized)

            for w in word_list:
                if w:
                    word_out.write(w+'\n')

            word_list = []

        except IndexError: 
            output.write(s[1])

        except UnboundLocalError:
            output.write(s[1])


def ensure_dir(directory):
    if not os.path.exists(directory):
        os.makedirs(directory)
    return directory    


def process_epubs(input_path, output_path):
    pool = mp.Pool()

    for root, dirs, files in os.walk(input_path):
        epubs = [os.path.join(root, file) for file in files
                 if file.endswith('.epub')]
        output_file = [
            ensure_dir(
                os.path.join(
                    output_path,
                    os.path.splitext(os.path.basename(e))[0] + '_output')
                for e in epubs)]

    for count, e in enumerate(epubs):
        epub = epubLoader(e)
        for filename, source in epub.get_html_from_epub():
            pool.apply_async(
                worker,
                args=(output_file[count], source, filename))
    pool.close()
    pool.join()

    print "done!"


if __name__ == '__main__':
    process_epubs('some local directory', 'some local directory')
于 2013-07-12T18:19:28.233 に答える