multicpu bzip2 с использованием скрипта Python - PullRequest
4 голосов
/ 27 июля 2010

Я хочу, чтобы bzip2 быстро сжимал несколько сотен гигабайт данных, используя мою 8-ядерную рабочую станцию ​​16 ГБ.В настоящее время я использую простой скрипт на python для сжатия всего дерева каталогов с помощью bzip2 и системного вызова os.s дополненного вызовом os.walk.

Я вижу, что bzip2 использует только один процессор, тогда как другой процессоростаются относительно простаивающими.

Я новичок в очереди и многопоточных процессах.Но мне интересно, как я могу реализовать это так, чтобы у меня могло быть четыре запущенных потока bzip2 (на самом деле я предполагаю, что потоки os.system), каждый из которых, вероятно, использует свой собственный процессор, который удаляет файлы из очереди при их bzip.1006 * Мой однопоточный скрипт вставлен сюда.

import os
import sys

for roots, dirlist , filelist in os.walk(os.curdir):
    for file in [os.path.join(roots,filegot) for filegot in filelist]:
        if "bz2" not in file:
            print "Compressing %s" % (file)
            os.system("bzip2 %s" % file)
            print ":DONE" 

Ответы [ 2 ]

1 голос
/ 22 октября 2010

Попробуйте этот код из MRAB на comp.lang.python:

import os 
import sys 
from threading import Thread, Lock 
from Queue import Queue 
def report(message): 
     mutex.acquire() 
     print message 
     sys.stdout.flush() 
     mutex.release() 
class Compressor(Thread): 
     def __init__(self, in_queue, out_queue): 
         Thread.__init__(self) 
         self.in_queue = in_queue 
         self.out_queue = out_queue 
     def run(self): 
         while True: 
             path = self.in_queue.get() 
             sys.stdout.flush() 
             if path is None: 
                 break 
             report("Compressing %s" % path) 
             os.system("bzip2 %s" % path) 
             report("Done %s" %  path) 
             self.out_queue.put(path) 
in_queue = Queue() 
out_queue = Queue() 
mutex = Lock() 
THREAD_COUNT = 4 
worker_list = [] 
for i in range(THREAD_COUNT): 
     worker = Compressor(in_queue, out_queue) 
     worker.start() 
     worker_list.append(worker) 
for roots, dirlist, filelist in os.walk(os.curdir): 
     for file in [os.path.join(roots, filegot) for filegot in filelist]: 
         if "bz2" not in file: 
             in_queue.put(file) 
for i in range(THREAD_COUNT): 
     in_queue.put(None) 
for worker in worker_list: 
     worker.join() 
1 голос
/ 27 июля 2010

Используйте модуль subprocess для запуска нескольких процессов одновременно. Если N из них запущены (N должно быть немного больше, чем количество имеющихся у вас процессоров, скажем, 3 для 2 ядер, 10 для 8), дождитесь завершения одного из них и затем запустите другое.

Обратите внимание, что это может не сильно помочь, поскольку будет много дисковой активности, которую вы не сможете распараллелить. Помогает много свободной оперативной памяти для кешей.

...