CronJob-Service
bei SELFPHP mit ...
|
+ minütlichen Aufrufen
+ eigenem Crontab Eintrag
+ unbegrenzten CronJobs
+ Statistiken
+ Beispielaufrufen
+ Control-Bereich
Führen Sie mit den CronJobs von
SELFPHP zeitgesteuert Programme
auf Ihrem Server
aus. Weitere Infos
|
:: Anbieterverzeichnis ::
Globale Branchen
Informieren Sie sich über ausgewählte Unternehmen im Anbieterverzeichnis von SELFPHP
:: Newsletter ::
Abonnieren Sie hier den kostenlosen
SELFPHP Newsletter!
|
PHP Entwicklung und Softwaredesign Hier können strukturelle (Programmier-) Konzepte diskutiert und Projekte vorgestellt werden |
04.06.2007, 09:17:12
|
Anfänger
|
|
Registriert seit: Jun 2007
Beiträge: 11
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Hallo,
das Problem wurde zwar nicht gelößt, aber der Weg zum Ziel ist nun leider ein anderer. Es ist nicht das, was ich wollte... aber wenigstens gehts auf die Weise.
Bitte fragt mich nicht, warum es mit einer while-Schleife geht und eine rekursive Funktion scheitert, denn nichts anderes habe ich getan (tun müssen).
Offensichtlich ein Apache-Bug
So werden alle Items angezeigt:
PHP-Code:
<?php
error_reporting(E_ALL);
function countChar($str,$search){
if(trim($str)==false || !strstr($str,$search))return 0;
$zeichen = array();
for ($i=0; $i<strlen($str); $i++)
if(isset($zeichen[$str{$i}]))$zeichen[$str{$i}]++;
else $zeichen[$str{$i}]=1;
return $zeichen[$search];
}
function printItem($str,$int){
echo "<code>($int) $str</code><br>\n";
return true;
}
//*** DEFINIERE ***
$int_max_item=4000;
$str_word='a*b*c*d';// (*) Zeichen werden ersetzt (egal, wie viele)
$int_ct_stern = countChar($str_word,'*');//Anzahl Zeichen
$ar_abc=array('ä','ö','ü','ß','+','-','a','b','c','d','e'
,'f','g','h','i','j','k','l','m','n','o'
,'p','q','r','s','t','u','v','w','x','y','z');//Pool an Zeichen
//$ar_pool defin., $ar_pool[$x]=Wert, Wert wird rekur. hochgezählt
//oder ggf. zurückgesetzt
for($x=0; $x<$int_ct_stern; $x++)$ar_pool[$x]=0;
$int_ct_abc = count($ar_abc);//Anzahl Zeichen
$int_last_x = $int_ct_stern-1;// letzter Schlüssel
$int_zaehler = 0;
//*** PRINT INFO ***
echo "<p><b>$int_ct_stern</b> Sternchen gefunden.<br>
<b>$int_ct_abc</b> Zeichen stehen zur Verfügung.<br>
Das enstpricht <b>".number_format(bcpow($int_ct_abc,$int_ct_stern,0),0,'','.')
."</b> Möglichkeiten<br>
<b>$int_max_item</b> Einträge sollen ausgegeben werden.</p>\n";
//*** START ***
while ( $ar_pool[0] < $int_ct_abc ) {
// 1. Prüfung der Werte (Testlauf)
// 2. Ersetzen der Sternchen und Ausgabe
// 3. In jedem Durchlauf wird ein Satz an Zeichen für das Ersetzen
// der Sternchen im nkommenden Durchlauf erzeugt
// (Anzahl entspr. der Sternchen).
$int_zaehler++;
$str_word2=$str_word;//Kopie vom Orig.
$ar_curr_abc=array();//Werte für 1 Einsatz
//So oft wie Sternchen vorhanden das Array
//mit den zugewiesenen Zeichen durchlaufen
//Werte Prüfen und Zeichen in curr_abc für das folgende Ersetzen def.
for($x=0; $x<$int_ct_stern; $x++){
if(!isset($ar_pool[$x]))die(" ERROR #".__LINE__." [$x] ");
if($ar_pool[0]>=$int_ct_abc)return;//die(" Pool Ende erreicht ");
if($ar_pool[$x] == $int_ct_abc)die(" ERROR #".__LINE__." ");
if(!isset($ar_abc[$ar_pool[$x]]))die(" ERROR #".__LINE__." ");
$ar_curr_abc[$x]=$ar_abc[$ar_pool[$x]];//zeichen def.
}
//Curr Zeichensatz verarbeiten
foreach($ar_curr_abc as $k => $v){
$t=strpos($str_word2,'*');
$str_word2{$t}=$v;
if(strpos($str_word2,'*')===false)
if(printItem($str_word2,$int_zaehler)==false)
die(" ERROR #".__LINE__." ");
}
//Neuen durchlauf vorbereiten
//Rückwärts aktualisieren
//Letzter zählt immer weiter, andere nur wenn Vorgänger Reset
$ar_reset=array();//Hilfs-Array, ob 0 im Vorg. wirklich aus einem Reset erfolgte
for($x=$int_last_x; $x >= 0; $x--){
if( $ar_pool[$x]+1 == $int_ct_abc && $x!=0
&& ($x==$int_last_x || isset($ar_reset[$x+1]))){
$ar_pool[$x]=0;//Reset
$ar_reset[$x]=true;
//nur beim letzten immer +1, sonst nur wenn Vorgänger Reset
}elseif( $x==$int_last_x || $x!=$int_last_x
&& ($ar_pool[$x+1])==0 && isset($ar_reset[$x+1])){
$ar_pool[$x]++;
}
}
//Ende, wenn Grenzwert für Ausgabe erreicht
if( $int_zaehler >= $int_max_item)break;
}
echo '<div style="height:300px"></div>';//Space
?>
Viele Grüße und danke an die, die mir antworteten,
Sven
|
04.06.2007, 09:46:29
|
SELFPHP Guru
|
|
Registriert seit: Jan 2004
Ort: Leipzig
Beiträge: 4.549
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Zitat:
Zitat von s.heinrich
Offensichtlich ein Apache-Bug
|
So wie es aussieht es ist Dein Windows-System, welches fehlerhaft konfiguriert wurde. Also mal wieder ein Pebcak.
|
04.06.2007, 10:18:08
|
Anfänger
|
|
Registriert seit: Jun 2007
Beiträge: 11
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Hallo,
Zitat:
So wie es aussieht es ist Dein Windows-System, welches fehlerhaft konfiguriert wurde. Also mal wieder ein Pebcak.
|
So wie es aussieht funktioniert das ausführliche Script bei dir prächtig und es wurde wieder mal eine Schublade geöffnet und geschlossen. Man kann sich's auch leicht machen...
Ich möchte dich noch auf Beitrag #9 hinweisen. Die Person, die ich um eine Einschätzung bat sitzt auf mehreren UNIX-Systemen und sieht die gleichen Probleme wie ich mit Apache auf WIN.
Warum gehts rekursiv nicht, aber mit while? Ich habe das Script selbst in den oben stehenden 2 Versionen auf einen Account hochgeladen und getestet - online(Linux/Apache) die gleichen Ergebnisse wie Lokal (Win/Apache). Das tat ich bevor ich den Experten zu Rate zog.
Danke für dein Interesse und die unangebrachte Häme.
Sven
|
04.06.2007, 10:48:02
|
SELFPHP Guru
|
|
Registriert seit: Jan 2004
Ort: Leipzig
Beiträge: 4.549
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Zitat:
Zitat von s.heinrich
Ich möchte dich noch auf Beitrag #9 hinweisen. Die Person, die ich um eine Einschätzung bat sitzt auf mehreren UNIX-Systemen und sieht die gleichen Probleme wie ich mit Apache auf WIN.
|
Dann kann eben der auch Windows nicht administrieren.
Zitat:
Warum gehts rekursiv nicht, aber mit while?
|
Weil Rekursion bekannterweise mehr Ressourcen verschlingt als Iteration, die offentsichlich auf den Systemen, bei denen der Fehler auftritt, nicht zur Verfügung stehen.
Und brauchst Dich nicht über unangebrachte Häme zu beschweren, wenn Du Deine Probleme einfach auf den Apache schiebst, der auch nichts für Deine config kann.
Geändert von feuervogel (04.06.2007 um 10:49:02 Uhr)
|
04.06.2007, 18:11:05
|
Anfänger
|
|
Registriert seit: Jun 2007
Beiträge: 11
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Hallo,
Zitat:
Zitat von feuervogel
Dann kann eben der auch Windows nicht administrieren.
|
Mit verurteilen sind wir schnell...Klasse! (es sind bei ihm Linux-Server)
Zitat:
Zitat von feuervogel
Weil Rekursion bekannterweise mehr Ressourcen verschlingt als Iteration, die offentsichlich auf den Systemen, bei denen der Fehler auftritt, nicht zur Verfügung stehen. Und brauchst Dich nicht über unangebrachte Häme zu beschweren, wenn Du Deine Probleme einfach auf den Apache schiebst, der auch nichts für Deine config kann.
|
Ja, ich hätte lieber PHP als Sündenbock hernehmen sollen. Schön, dass du JETZT die Ressourcen ansprichst, nachdem das Script bei dir auch nicht läuft...
Zitat:
Zitat von feuervogel
So wie es aussieht es ist Dein Windows-System, welches fehlerhaft konfiguriert wurde. Also mal wieder ein Pebcak.
|
Da es beim besagten Systembetr. auch nicht ging, und in seinem error-log kein Eintrag zu sehen war, hat er meinen Code an einen Guru weitergesendet. Von einer falschen Konfiguration kann ich aber mein besten Will nichts in der Begründung sehen/lesen, was ja bislang dein Argument ist/war:
Zitat:
Es liegt an der rekursiven Funktion: Jeder Aufruf bewirkt eine Reservierung von Speicher im sog. Stack. Sichtbar ist hierbei immer nur die oberste Stackebene. Dieser Stack muss sich mit dem eigentlichen Programm (also dem Script und dem Parser mod_php) den Speicher teilen. Würde man sich das Ganze mit einem Debugger ansehen, würde man feststellen, dass der Speicherbedarf nicht linear, sondern zyklisch anwächst. Es wird mit jedem Zyklus (rekursivem Aufruf) nicht nur die Funktion, sondern auch das Ergebnis samt Variablen der Funktion abgelegt.
PHP ist nun so ausgelegt, dass es "selbständig" nach einer Weile feststellt (oder glaubt festzustellen), wenn ein rekursiver Aufruf in einer Endlosschleife enden würde, da keine Abbruchbedingung innerhalb der Rekursivfunktion hinterlegt ist. Und genau das ist der Knackpunkt: Je nach Auslastung des Speichers begrenzt PHP die Durchläufe einer solchen rekursiven Funktion. So sollte man bei mehr als 500 rekursiven Aufrufen auf Iterationen umsteigen (also while, for-next, do-until, etc.), da diese bei solchen Mengen bis zu 800% schneller abgearbeitet werden, als rekursive Aufrufe einer Funktion.
|
Wäre dies deine Antwort gewesen, dann: Hut ab!
Viel Spaß noch mit den Hilfesuchenden,
Sven
PS: Manche müssen erst nach unten treten um zu wachsen.
|
04.06.2007, 19:32:08
|
|
SELFPHP Guru
|
|
Registriert seit: Dec 2003
Ort: Erfurt
Alter: 75
Beiträge: 4.001
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Zitat:
Zitat von s.heinrich
So wie es aussieht funktioniert das ausführliche Script bei dir prächtig und es wurde wieder mal eine Schublade geöffnet und geschlossen. Man kann sich's auch leicht machen...
|
Auf einen Konfigurationsfehler hatte ich Dich ja hingewiesen. Offenbar vergeblich...
Zitat:
Zitat von s.heinrich
Da es beim besagten Systembetr. auch nicht ging, und in seinem error-log kein Eintrag zu sehen war, hat er meinen Code an einen Guru weitergesendet. Von einer falschen Konfiguration kann ich aber mein besten Will nichts in der Begründung sehen/lesen,
|
Der hatte ja auch nicht gesehen, daß Du auf einer Windowskiste PHP gesagt hattest, es möchte sein error_log nach /dev/null schicken.
Zitat:
Wäre dies deine Antwort gewesen, dann: Hut ab!
|
Meine Fresse! Das muß Dir doch der gesunde Menschenverstand sagen, daß der mehrfache Aufruf einer Funktion mehr Speicher frißt als eine lumpige Schleife, die durch ein Array latscht.
Ich selber verwende Rekursionen bis maximal 10 Ebenen, weil mir dazu der RAM einfach zu schade ist.
Geändert von meikel (†) (04.06.2007 um 23:12:10 Uhr)
|
04.06.2007, 22:54:52
|
SELFPHP Guru
|
|
Registriert seit: Jan 2004
Ort: Leipzig
Beiträge: 4.549
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Zitat:
Schön, dass du JETZT die Ressourcen ansprichst, nachdem das Script bei dir auch nicht läuft...
|
hm, mit 2000 schritten läuft es. versuche ich es mit 100000, bricht es irgendwo hinter der 16000 ab. im error-log meines apaches steht:
Zitat:
[Mon Jun 04 22:41:44 2007] [notice] child pid 6213 exit signal Segmentation fault (11)
|
bemüht man nun google ein wenig, findet man folgendes:
Zitat:
The problem with PHP isn't so much that there is a limit to the amount of recursion. Instead it is that the interpreter has a Segmentation Fault when the function stack is full, causing PHP to crash.
|
es gibt also eine limitierung was die menge der rekursiven schritte angeht. die sitzt bei dir offentsichtlich zu niedrig, für das, was du vorhast, und zudem gibt es keine gescheiten einträge in deinem error-log. ich hab keine ahnung, wo meine grenze genau sitzt, da ich rekursion möglichst meide.
Zitat:
Da es beim besagten Systembetr. auch nicht ging, und in seinem error-log kein Eintrag zu sehen war,
|
dann lies entweder meikels postings oder versuche mal /dev/null zu finden auf deiner kiste.
|
04.06.2007, 23:09:05
|
Anfänger
|
|
Registriert seit: Jun 2007
Beiträge: 11
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
...moment
Geändert von s.heinrich (04.06.2007 um 23:09:17 Uhr)
|
05.06.2007, 00:12:47
|
Anfänger
|
|
Registriert seit: Jun 2007
Beiträge: 11
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Hallo,
@meikel
>>Auf einen Konfigurationsfehler hatte ich Dich ja hingewiesen. Offenbar um sonst...<<
Nein! Ich habe stundenlang gegooglet und nach Lösungen oder hinweisen gesucht, also Infos zum Quell "des Übels". Nach wenig konstruktiven Infos wollte ich einen anderen Weg zur Fehlersuche einschlagen (die Hartnäckigkeit entschuldigend): Wenns bei anderen geht und die Linux einsetzen, dann Frage ich doch einen, der Linux hat und vielleicht ein wenig Zeit investieren würde, um in sein Log reinzuschauen. Euch wollte ich nicht damit belästigen. Er machte dies und sah ebenso wie ich Abbrüche und keinen Fehler im error_log, kennt aber einen Guru recht gut. Also schickte er die Daten weiter und zurück kam der erste klärende Text.
>>Der hatte ja auch nicht gesehen, daß Du auf einer Windowskiste PHP gesagt hattest, es möchte sein error_log nach /dev/null schicken.<<
Ja, er kannte nur das Linux-System meines "Probanten" (der mit den gleichen Abbrüchen).
>>Meine Fresse! Das muß Dir doch der gesunde Menschenverstand sagen, daß der mehrfache Aufruf einer Funktion mehr Speicher frißt als eine lumpige Schleife, die durch ein Array latscht. Ich selber verwende Rekursionen mis maximal 10 Ebenen, weil mir dazu der RAM einfach zu schade ist.<<
Nicht meine Form etwas auszudrücken, aber hilfreich! Diese Aussage hätte mir den Wechsel zur while-Schleife leichter gemacht und ein paar Stunden gespart. Kaum auszumalen, in welchem Zustand mein Verstand sein muss. Sorry, dass ich mit meinem kleinen Problem hier aufschlage. Wenn doch jeder des Rätsels Lösung wissen müsste hätt ichs doch beim googlen finden müssen.
@feuervogel
Danke für die Info. Die Suche habe ich eingestellt, denn mit der while-Schleife sind keine error_log-Einträge zu sehen (nicht mal in meinem WIN-Sys) und wie ich jetzt lernen durfte, sind Schleifen den Funktionen bei sehr vielen Aufrufen vorzuziehen.
Viele Grüße und danke für Eure Zeit,
Sven Heidrich
PS: Ein fairer Umgang ist sicherlich etwas Zeitintensiver - bringt aber erfahrungsgemäß auf lange Sicht ein gutes Klima ins Forum.
|
05.06.2007, 01:21:49
|
|
SELFPHP Guru
|
|
Registriert seit: Dec 2003
Ort: Erfurt
Alter: 75
Beiträge: 4.001
|
|
AW: Einfache Rekursive Funktion - Ausgabe wird abgebrochen
Zitat:
Zitat von s.heinrich
Nicht meine Form etwas auszudrücken, aber hilfreich!
|
Erfreulich. Denke immer daran, daß Deine Scripte auf einem gut besuchten Webserver mehrfach aufgerufen werden. Da muß man neben der Scriptlaufzeit auch mit dem Speicher sparen. Es sieht nicht besonders gut aus, wenn nach 10 sec. nur noch eine Fehlermeldung angezeigt werden kann...
Natürlich hast Du in gewisser Beziehung recht, wenn Du von einem Bug sprichst, weil PHP den Stackpointer mangelhaft verwaltet.
Zitat:
Viele Grüße und danke für Eure Zeit,
|
Viel Erfolg noch!
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
Alle Zeitangaben in WEZ +2. Es ist jetzt 04:14:01 Uhr.
|