2016-07-25 15 views
-1

Ich habe einen sehr ressourcenintensiven Code, den ich erstellt habe, sodass ich die Arbeitslast auf mehrere Pthreads aufteilen kann. Während alles funktioniert, ist die Berechnung schneller, usw. Was ich vermute, ist, dass andere Prozesse auf diesem Prozessorkern so langsam werden, dass sie nach ein paar Sekunden Laufzeit abstürzen.Ressourcenintensives Multithreading, das andere Prozesse zerstört

Ich schon geschafft, zufällige Prozesse wie Chrome Tabs, die Cinnamon DE oder sogar das gesamte Betriebssystem (Kernel?) Zu töten.

Code: (Es ist spät, und ich bin zu müde, um einen Pseudo-Code oder sogar Kommentare ..) - Aber es ist ein Brute-Force-Code, nicht so sehr zum Knacken, sondern zum Testen von Passwörtern und oder CPU IPS.

Irgendwelche Ideen, wie Sie dies beheben können, während Sie immer noch so viel Leistung wie möglich halten?

static unsigned int NTHREADS = std::thread::hardware_concurrency(); 
static int   THREAD_COMPLETE = -1; 
static std::string PASSWORD = ""; 
static std::string CHARS; 
static std::mutex  MUTEX; 

void *find_seq(void *arg_0) 
{ 
    unsigned int _arg_0 = *((unsigned int *) arg_0); 
    std::string *str_CURRENT = new std::string(" "); 

    while (true) 
    { 
    for (unsigned int loop_0 = _arg_0; loop_0 < CHARS.length() - 1; loop_0 += NTHREADS) 
    { 
     str_CURRENT->back() = CHARS[loop_0]; 

     if (*str_CURRENT == PASSWORD) 
     { 
     THREAD_COMPLETE = _arg_0; 
     return (void *) str_CURRENT; 
     } 
    } 

    str_CURRENT->back() = CHARS.back(); 

    for (int loop_1 = (str_CURRENT->length() - 1); loop_1 >= 0; loop_1--) 
    { 
     if (str_CURRENT->at(loop_1) == CHARS.back()) 
     { 
     if (loop_1 == 0) 
      str_CURRENT->assign(str_CURRENT->length() + 1, CHARS.front()); 
     else 
     { 
      str_CURRENT->at(loop_1) =  CHARS.front(); 
      str_CURRENT->at(loop_1 - 1) = CHARS[CHARS.find(str_CURRENT->at(loop_1 - 1)) + 1]; 
     } 
     } 
    } 
    }; 
} 
+2

Die Symptome, die Sie beschreiben, die eines der Speicher Situation durch einen Speicher oder Ressourcen-Leck verursacht werden, unter Berufung auf die [oom Killer] (https: // www .memset.com/docs/additional-information/oom-killer /) – kfsone

+0

@kfsone Klingt wahrscheinlich, aber die Anwendung verwendet maximal 20 MB, und Valgrind meldet Folgendes: möglicherweise verloren: 2,223 Bytes in 14 Blöcken && noch erreichbar: 56 Bytes in 7 Blöcken. Natürlich, es gibt einige Lecks, die ich versuchen werde zu beheben, aber manchmal gibt Valgrind ungenaue Daten. – areuz

+1

Ein Prozess, der die CPU nervt, sollte nicht in der Lage sein, andere Prozesse zum Absturz zu bringen. Es wird sie verlangsamen, aber kann sie nur aufgrund von fehlerhafter Hardware oder einem Kernel-Bug zum Absturz bringen. –

Antwort

0

Vielen Dank für Ihre Antworten und vor allem Matthew Fisher für seinen Vorschlag, es auf einem anderen System zu versuchen.


Nach einiger Versuch und Irrtum habe ich beschlossen, meine CPU übertakten zurück zu ziehen, dass ich dachte stabil war (ich hatte es mehr als ein Jahr für), und dass dieses seltsame Verhalten gelöst. Ich nehme an, dass ich noch nie eine solche CPU intensiv und (ich vermute) effizient betrieben habe (um die volle CPU nicht durch Nachgeben zu drosseln), um das zu sehen.

Wie Matthew vorgeschlagen, muss ich einen besseren Weg finden als nur die Variable THREAD_COMPLETE mit einer while true Schleife ständig zu überprüfen, aber ich hoffe, das in den Kommentaren aufzulösen.

Voll und aktualisierten Code für zukünftige Besucher ist hier: pastebin.com/jbiYyKBu

1

Areuz,

Können Sie den vollständigen Code posten? Ich vermute, dass das Problem der NTHREADS-Wert ist. In meiner Ubuntu-Box wird der Wert auf 8 gesetzt, was der Anzahl der Kerne in der Datei/proc/cpuinfo entspricht. Wenn ich 8 'heiße' Threads auf meiner Box starte, werden 100% der CPU verbraucht. Der Kernel wird die Zeit für seine eigenen kritischen Prozesse einteilen, aber im Allgemeinen werden alle anderen Prozesse nach CPU hungern.

Überprüfen Sie den maximalen Prozessorwert in/etc/cpuinfo und gehen Sie mindestens einen niedrigeren als das. Die CPUs sind auf meiner Box mit 0-7 nummeriert, also wäre 7 das Maximum für mich. Das tatsächliche Maximum könnte 3 sein, da 4 meiner Kerne Hyper-Threads sind. Für vollständige CPU-Prozesse hilft Hyper-Threading im Allgemeinen nicht.

Bottom line, nicht die ganze CPU Schwein, wird es das System destabilisieren.

--Matt

+0

Ich habe ein i7 3770K @ 4,8GHz. Es hat 8 Threads. Ich habe offensichtlich versucht, alle Threads für erhöhte Leistung zu verwenden.Ich frage mich nur, warum so etwas wie der "Stress" -Befehl die gesamte CPU nutzen kann, ohne irgendetwas zu zerstören. P.S. Auch wenn ich nur ein paar Threads verwende, werden die Prozesse, die auf diesen Threads ausgeführt werden, wie ich bereits sagte, einige meiner Chrome-Tabs usw. mit der Zeit zum Absturz bringen. Voller Code, nur für eine gute Maßnahme: http://pastebin.com/jbiYyKBu – areuz

+0

Ich entschied mich, den "Stress" Quellcode zu betrachten, und ich bin jetzt noch mehr verwirrt. Ich kann die ganze CPU den ganzen Tag damit belasten, also habe ich irgendeinen ausgeklügelten Code erwartet, um für einige Zeit zu schlafen oder einfach die Priorität zu senken. Aber der Literalcode zum Betonen von CPU mit diesem Befehl ist: 'hogcpu (void) { während (1) sqrt (rand()); Rückgabe 0; } ' – areuz

+0

Hmm, keine Freude. Ich habe den Code lokal ohne Probleme ausgeführt. Es hat meine 8 Kerne ausgereizt, aber die Box funktionierte immer noch gut. Ich lief ungefähr 20 Minuten ohne Probleme. Ubuntu 14.04. Können Sie eine andere Box anprobieren? AWS hat kostenlose Accounts. Als Nebenbemerkung läuft die while-Schleife in main unter Verwendung eines anderen Kerns. Pthread_join kann verwendet werden, um zu überwachen, ob ein Thread beendet wird. THREAD_COMPLETE kann als Flag für die Threads verwendet werden, die beendet werden, und nicht als while (1) –