Paralleles packen von Dateien

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von Der_Wolf, 23.07.2008.

  1. #1 Der_Wolf, 23.07.2008
    Zuletzt bearbeitet: 23.07.2008
    Der_Wolf

    Der_Wolf Jungspund

    Dabei seit:
    23.07.2008
    Beiträge:
    13
    Zustimmungen:
    0
    Sehr geehrte Dame und Herren,

    ich bin neu hier im forum deshalb begrüsse ich alle recht herzlich :).

    Ich habe ein Problem, ich habe auf einem Raid Server ca 4 TB Daten. Um das Datenaufkommen zu verringern möchte ich Dateien in bestimmten Ordnern packen. Wenn ich diese Aufgabe von einem einzelnen Prozess erledigen lassen würde, würde das sehr lange dauern da nur ein Prozessor genutzt werden könnte. Ich habe ein shell script geschrieben das zu packenden Daten mittels find sucht.
    Nun möchte ich mind. zwei Prozessoren parallel damit beauftragen diese gefundenen Daten zu packen.

    Mein Ansatz war das Ergebnis von find in eine Textdatei zu schreiben. Sie enthält Zeilenweise jede Datei die gepackt werden muss. Nun wollte ich mit "wc" die Anzahl der Zeilen ermitteln und durch die Anzahl der zu benutzenden Prozessoren (eventuell Eingabeparameter) teilen. Anschliessend sollten "Workerprozesse" gestartet werden (ich dachte an exec ... &) die jeweils als Eingabeparameter einen Zeilenbereich für die Datei erhalten, den Dateinamen mit "cut" holen und somit vollkommen parallel arbeiten können.

    Leider ist mein Wissen über shell programmierung nicht fundiert genug um dies zu realisieren.
    Ich wäre euch sehr dankbar wenn ihr mir einen Denkanstoss :headup: geben könntet ob dieser Weg realisierbar ist, oder ob es viel einfacher geht.

    mit freundlichen grüssen
    Denny S. :brav:
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. foexle

    foexle Kaiser

    Dabei seit:
    02.05.2007
    Beiträge:
    1.104
    Zustimmungen:
    0
    Ort:
    Saarbrücken
    Hi und willkommen im board :>
    Also kurz nochmal zum verständnis du willst nicht alle gefundenen dateien in ein archiv packen und comprimieren ? sondern jede datei einzeln ?
    Wenn du jede datei einzeln machen willst, würde ich persönlich das nicht mit shellskript realisieren sondern ein kleine c-proggi schreiben und mit fork() arbeiten !

    Aber bestimmt gibts hier auch leute, die dir ein bsp in einem shellskript geben können
     
  4. #3 Der_Wolf, 23.07.2008
    Der_Wolf

    Der_Wolf Jungspund

    Dabei seit:
    23.07.2008
    Beiträge:
    13
    Zustimmungen:
    0
    Danke foexle für deine Antwort :).

    Ja du hast natürlich recht ich möchte jede Datei einzeln einpacken.
    Mit nen C Programm und fork wäre es natürlich auch realisierbar aber ich favorisiere ein shell script.

    Die Frage ist eigentlich bei meinem Ansatz wie kann ich die Zeilen der Datei (die die einzelenen Dateinamen+Pfad) enthält auf die Anzahl der Prozessoren aufteilen. "wc" gibt eine Gesamtzahl der Zeilen an, allerding weiss ich nicht wie ich dem Kommando ein Ergebnis entlocke mit dem ich rechnen kann, um die Anzahl der Zeilen durch die zu verwenden Proz. teilt.

    Dann die Frage wie man an die bestimmten Zeilen ran kommt wenn man den Index hat. Entweder mit "cut" irgendwie oder mit split die Datei aufteilen in x gleiche Teile und jedem Prozessor eine Teildatei bearbeiten lassen ???????

    Beim starten der Workerprozesse, geht das mit exec ..... & ??? Um parall mehere zu starten und jedem entweder eine eigene Datei zukommen lassen oder einen Indexbereich?

    mit freundlichen Grüssen

    Denny
     
  5. foexle

    foexle Kaiser

    Dabei seit:
    02.05.2007
    Beiträge:
    1.104
    Zustimmungen:
    0
    Ort:
    Saarbrücken
    Also ein wenig kann ich dir helfen :>

    Code:
    cpuAnzahl=$1
    
    `find /verzeichnis -name *.avi >> verzeichnisse.txt`
    anzahl = `cat ~/verzeichnisse.txt | wc -l`
    gesAnzahl= `expr $anzahl / $cpuAnzahl`
    
    also ungetestet dann haste die Zahl :>
     
  6. #5 Der_Wolf, 23.07.2008
    Zuletzt bearbeitet: 23.07.2008
    Der_Wolf

    Der_Wolf Jungspund

    Dabei seit:
    23.07.2008
    Beiträge:
    13
    Zustimmungen:
    0
    foexle, dankeschön.

    Das funktioniert schonmal :).

    Code:
    $CPUs 
    $Anzahl 
    $Teilmenge
    
    find $1 -wholename "*suchmuster" -print  >  print.txt 
    CPUs=2
    Anzahl=$(cat print.txt | wc -l)
    echo "Gesamtdateien $Anzahl"
    echo "Gesamtkerne $CPUs"
    Teilmenge=$((Anzahl/CPUs))
    echo "Dateien pro Kern $Teilmenge"
    
    Nun hab ich die Zahlen die ich brauche :).

    Das nächste Problem ist ob es einen Befehl gibt um auf die Indexe der spalten gezielt zuzugreifen. oder ob man die Quelldatei in soviele Teile teilt wie man Kerne hat und jedem Kern eine extra Datei zur Verfügung stellt um diese Daten abzuarbeiten.

    Ich denke die Datei teilen wäre am besten nur wie teilt man diese, bzw welches kommando ermöglicht es z.B. Zeile 100-200 in eine andere Datei zu speichern ?? Ich werds mal mit sed versuchen, falls wer ne andere Idee hat bitte posten.

    mfg
    Denny
     
  7. foexle

    foexle Kaiser

    Dabei seit:
    02.05.2007
    Beiträge:
    1.104
    Zustimmungen:
    0
    Ort:
    Saarbrücken
    ja sicher kannst du die datei teilen ....
    machst ne schleife die so oft durchläuft wie $cpu groß ist,
    anhand der durchlaufnummer machste ne datei wie "datei$i"
    dann machste eine innere schleife die so oft durchläuft wie $teilmenge
    und kopierst einfach jede zeile in datei$i

    das wars... dann haste so viele dateien wie cpus und hast da so viel drin wie der durchschnitt ist... aber achtung du weist das dir evtl zeilen verloregn gehen können wegen der rundung ... oder gehen die zeilen immer auf ? also wenn du zeilen/cpu rechnest ?

    greetz
     
  8. #7 marcellus, 24.07.2008
    marcellus

    marcellus Kaiser

    Dabei seit:
    09.05.2007
    Beiträge:
    1.392
    Zustimmungen:
    0
    Wie wärs mit

    Code:
    #!/bin/bash
    
    LZS="
    "
    procs="0"
    cpus="0" #selbst eintragen
    
    for i in $(cat $1)
    do
            if      [ $cpus -gt $procs ]
            then
                    procs=$[ $procs+1 ]
                    bzip2 $i ; procs=$[ $procs-1 ] &
            else
                    sleep 1s 
            fi 
    done
    
    nicht geteste, aber es sollte zu mindest so ähnlich ablaufen.

    Ich glaub aber irgendwo gelesen zu haben, dass es eine implementierung von bzip gibt, die multithreading unterstützt, vllt bist du damit glücklicher.
     
  9. #8 Der_Wolf, 24.07.2008
    Zuletzt bearbeitet: 24.07.2008
    Der_Wolf

    Der_Wolf Jungspund

    Dabei seit:
    23.07.2008
    Beiträge:
    13
    Zustimmungen:
    0
    Also ihr zwei,

    ich danke euch vielmals für eure Tips, aber leider komme ich heute nicht mehr zum testen.
    Wenn ich Zeit habe werde ich morgen Nachmittag testen und meine Ergebnisse hier posten das auch andere was davon haben :).

    @foexle: mit welchem Befehl kann man denn Zeilenweise kopieren ??

    @marcellus: ja das mit der mutithreaded version von bzip klingt schon interessant, aber ich habe auch noch andere scripte die ich ausführen muss und da würde ich dann das gleiche Prinzip anwenden können um die Bearbeitung zu beschleunigen :).

    mfg
    Denny
     
  10. #9 marcellus, 24.07.2008
    Zuletzt bearbeitet: 24.07.2008
    marcellus

    marcellus Kaiser

    Dabei seit:
    09.05.2007
    Beiträge:
    1.392
    Zustimmungen:
    0
    Deswegen hab ich dir auch das script gepostet, das packt die einträge in deiner datei zeile für zeile, wobei $cpus viele pack prozesse gleichzeitig ablaufen.


    Edit: hab oben mist gebaut, es sollte eigentlich so aussehen:
    Code:
    #!/bin/bash
    
    LZS="
    "
    procs="0"
    cpus="0" #selbst eintragen
    
    for i in $(cat $1)
    do
    while [ $cpus -le $procs ]
            do
                    sleep 1s
            done
            procs=$[ $procs+1 ]
            $(bzip2 $i ; procs=$[ $procs-1 ] )&
    done
    
     
  11. #10 Der_Wolf, 24.07.2008
    Der_Wolf

    Der_Wolf Jungspund

    Dabei seit:
    23.07.2008
    Beiträge:
    13
    Zustimmungen:
    0
    Ich danke dir marcellus,

    ich werde mal versuchen nachzuvollziehen was das Script genau macht (wie gesagt ich hab leider noch nicht so viel Erfahrung mit shell scripten, aber Übung macht den Meister :) )und es anzuwenden :)

    mfg
    Denny
     
  12. #11 marcellus, 24.07.2008
    marcellus

    marcellus Kaiser

    Dabei seit:
    09.05.2007
    Beiträge:
    1.392
    Zustimmungen:
    0
    Ich hab das gerade noch einmal ausprobiert und muss gestehen, dass ich doch ein ziemlicher noob bin was shell programmierung angeht, das ganze haut so nicht hin, weil durch

    $(bzip2 $i ; procs=$[ $procs-1 ] )&

    eine neue shell aufgemacht wird, die dann nur eine kopie von procs dekrementiert.

    Ich bin mir sicher es gibt eine saubere lösung wie man das mit pointern lösen kann, aber meine jetzt funktionierende version soll dir nicht erspart bleiben ^^

    Code:
    #!/bin/bash
    
    LZS="
    "
    cpus="0"
    
    for i in $1
    do
            while [ $cpus -le $(jobs | wc -l) ]
            do
                    sleep 1s 
            done
            bzip2 $i &
    done
    
    sry für das mehrfache posten von falschem zeug, ich hab selber nicht übermäßig viel ahnung und wollt dein problem als herausforderung sehen.
     
  13. foexle

    foexle Kaiser

    Dabei seit:
    02.05.2007
    Beiträge:
    1.104
    Zustimmungen:
    0
    Ort:
    Saarbrücken
    ja kollege :> ich schreib dir doch nicht dein script :> das mussu schon selber machen... willst doch auch was lernen ... oben habsch dir einen weg beschrieben wie es gehen könnte ... nun schlägst du nach wie man schleifen baut, wie man von einer datei etwas in eine andere umlenkt und dann kannste den nächsten schritt angehen :>
     
  14. #13 supersucker, 25.07.2008
    Zuletzt bearbeitet: 25.07.2008
    supersucker

    supersucker Foren Gott

    Dabei seit:
    21.02.2005
    Beiträge:
    3.873
    Zustimmungen:
    0
    Damit eine Applikation mehrere CPUs nutzen kann, muss sie Threading verwenden.

    Da kannst du alles was mit Bash zu tun schon mal vergessen, die kann das nämlich nicht.

    Sprich, du wirst eine Hochsprache wie C++ oder Java verwenden müssen, die dir Threading anbietet.

    Mit Bash wird das schlicht und ergreifend nicht gehen.
     
  15. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  16. #14 marcellus, 25.07.2008
    marcellus

    marcellus Kaiser

    Dabei seit:
    09.05.2007
    Beiträge:
    1.392
    Zustimmungen:
    0
    @supersucker willst du damit sagen, dass es nicht möglich ist mit der bash mehrere Prozesse zu starten, oder willst du sagen, dass es nicht möglich ist, dass mehrere prozesse auf mehrere Kerne aufgeteilt werden?

    Und im übrigen gibts pthreads auch für c und viele andere prozedurale sprachen auch.
     
  17. #15 supersucker, 25.07.2008
    supersucker

    supersucker Foren Gott

    Dabei seit:
    21.02.2005
    Beiträge:
    3.873
    Zustimmungen:
    0
    Letzteres ist mit der Bash nicht möglich.

    Äh, ja?

    Hast du jetzt von mir erwartet, das ich alle Sprachen aufzähle, die Threading unterstützen?
     
Thema:

Paralleles packen von Dateien

Die Seite wird geladen...

Paralleles packen von Dateien - Ähnliche Themen

  1. Git 2.8 unterstützt paralleles Laden von Submodulen

    Git 2.8 unterstützt paralleles Laden von Submodulen: Mit der Freigabe von Git 2.8.0 haben die Entwickler das Quellcode-Verwaltungssystem um diverse neue Funktionen ergänzt. Die wohl prominenteste...
  2. initng: Paralleles Booten unter Linux

    initng: Paralleles Booten unter Linux: siehe auch: http://www.unixboard.de/comments.php?catid=25&id=903 wie sind eure meinungen dazu? suse hat seit der version 9.x auch sowas wie...
  3. Informationen in .semaphore packen & senden

    Informationen in .semaphore packen & senden: Hallo zusammen nach der für mich erfolglosen Suche im Internet nach passenden Informationen wende ich mich an Euch mit der Bitte mir in...
  4. Problem beim entpacken von Paketen

    Problem beim entpacken von Paketen: Moin, habe mir ein Wallpaper geloadet und wollte nun das komprimierte Paket entpacken. (Eigentlich keine große Sache) Datei: sunrise.tar.gz...
  5. Raw Video in Avi packen? avc2avi fuer Linux?

    Raw Video in Avi packen? avc2avi fuer Linux?: Hi Leute, ich stehe vor einem Problem mit einer TS Datei, von der Skystar HD2 (dvb-s2) aufgenommen. Unter Windows Xp, nur mal so am Rand. Nun...