Paralleles packen von Dateien

Hallo,

erstmal danke an alle die helfen wollten :).
Also na klar muss mir hier niemand nen fertiges Script geben, aber wenn ers doch macht bin ich nicht böhse :). Denn auch das werd ich vorher genau untersuchen und nicht einfach blind auf meine Daten loslassen.

Zu dem Problem selber. Multithreading ist natürlich was anderes als multitasking. Aber mir kommt es darauf an die Verarbeitung zu beschleunigen. Der Vorteil am Multitasking, also das starten mehrer gleicher Prozesse (bzip in diesem Beispiel), in Verbindung mit dem teilen der Datei die alle zu verarbeitenden Dateinamen + Pfad enthält, ist das ich dann nicht nur auf Kerne in einem Rechner sondern sogar auf mehere Rechner verteilen kann indem jeder Prozess nur ein Teil der Datei bearbeitet. OK irgendwann kommt das Netzwerk und macht Schluss mit den Spierenzchen. Aber bis dahin ist das eine verdammt flexible und vor allem sichere Lösung, da die Verarbeitung völlig parallel ablaufen kann ohne Querverbindung bzw. Kommunikation (lockfiles, ...) wenn die Quelldatei erstmal in x Teile geteilt ist.

mfg

Denny
 
Hallo,

Dein Vorhaben lässt sich gut mit Perl lösen, benötigte Perl-Pakete sollten standardmäßig installiert sein. Das nachstehende Script dpack.pl liest Dateinamen aus STDIN und packt bis zu NUMBEROFTHREADS Dateien parallel.

Vorausgesetzt es existiert ein Verzeichnis ./input, dann kann man so alle Textdateien packen:
Code:
find ./input/ -iname "*.txt" | ./dpack.pl
Noch was zur Anzahl der Threads: Ich wüde vorsichtig sein, mehr Threads zu starten, als man Kerne hat. In diesem Fall kann sogar der Effekt auftreten, dass "viele" Threads zu Performance-Einbußen führen, da je nach Ausstattung die Festplatte als Flaschenhals dafür sorgt, dass die Threads den überwiegenden Teil der Rechenzeit idle sind und auf Input warten. Ganz zu schweigen davon, dass die Antwortzeit des Servers in Mitleidenschaft gezogen wird.

PHP:
#!/usr/bin/perl

use threads;
use Thread::Semaphore;

use constant NUMBEROFTHREADS => 4;

use constant PACKER => '/usr/bin/bzip2 -9';

# Semaphor: Begrenzer für die Anzahl der Threads
$semaphore = Thread::Semaphore->new(NUMBEROFTHREADS);

# Unterroutine für einen Pack-Job
sub do_job {
	my $srcFilepath = shift @_;

	my $COMMAND = PACKER." \"$srcFilepath\"";

	# Kommando ausführen
 	my $result = `$COMMAND 2>&1`;

	# Laut geben, wenn was schiefgeht
	if ( $? ) {
		printf sprintf("Thread: %d fehlgeschlagen! %s: %s\n",
			threads->self->tid, $COMMAND, $result);
	}

	# Semaphor inkrementieren/freigeben.
	$semaphore->up();
}

# Dateinamen aus STDIN auslesen solange wie geht
while ( $line = <STDIN> ) {
	chomp($line);

	# Semaphor belegen/dekrementieren.
	# Wenn <0, blockiert es hier. Es laufen
	# nie mehr als NUMBEROFTHREADS
	$semaphore->down();

	# Thread starten
	my $thr = threads->new(\&do_job, $line);
}

# solange Threads laufen abwarten bis fertig
foreach $thr (threads->list) {
	# Don't join the main thread or ourselves
	if ($thr->tid && !threads::equal($thr, threads->self)) {
		$stillRunning = 1;
		$thr->join;
	}
}
 
Zuletzt bearbeitet:
Zurück
Oben