(fast) gleichzeitig Elemente Vectoren hinzufügen



  • Meist bricht er in der ersten Zeile des try-Blocks ab. Das ist die Methode:

    string settings_reader::get_value(string setting_name)
    {
    	for (int i = 0; i < m_setting.size(); i++)   // m_settings ist ein vector<string>
    		if (m_setting[i] == setting_name){   // Abbruch
    			return m_values[i];
    		}
    	return "nA";
    }
    

    Beim Debuggen brach er einmal im zweiten Durchlauf, einmal beim ersten Durchlauf ab. Die Fehlermeldung(en): manchmal "*** Abgestürzt mit Rückgabewert: 0 ", manchmal " Programm hat Signal SIGSEGV (Segmentation fault) empfangen ***".

    Auf dieses Objekt haben ja beide Threads Zugriff, bzw. vorher auch schon genutzt. Kann es da sein, dass der eine Thread, der eigentlich wartet, das Objekt, bzw. dessen vector noch blockiert?



  • Ist i innerhalb der Größe des vectors?



  • Wie ich schon gesagt habe, kann es nicht an der Methode selber liegen, da mit einem Thread alles läuft, der Fehler aber erst bei zwei gleichzeitigen Threads kommt. Die Threads selber ändern die Objekte nicht. (Mir fällt dabei auf, dass ich die Methode nicht als const definiert habe, ist gerade nachgeholt worden).

    edit: hier stand Mist. Beide Vektoren haben die gleiche Größe, das ist garantiert.



  • Mach doch einfach mal ein assert(m_setting.size() == m_values.size() ) an den Anfang.



  • Ich habe mir die Größe der Vektoren auch explizit ausgeben lassen, beide sind immer gleich.



  • Was passiert den, wenn du in der Funktion einfach immer "nA" zurück gibst?



  • Das ist schwierig, weil die Methode schon vorher öfters benutzt wird. Ich habe aber mal die Zeile auskommentiert und stattdessen explizit einen Wert angegeben:

    // 			string s = ArticleView->get_settingsreader()->get_value("temp_download_directory");
    			string s = "/tmp/";
    			s += ArticleView->get_article()->hash + ".htm";
    			article* a = ArticleView->get_article();
    

    Das Programm bricht dann bei der nachfolgenden Zeile, bzw. beim Aufruf von ArticleView->get_article()->hash. Auch ArticleView ist ein Pointer, den beide Threads nutzen. Auch hier bricht er nur ab, wenn ich das mit zwei Threads gleichzeitig ausführe.



  • ist bei if(blablabla) blablabla true ?



  • Ja, das ist ein länglicher Ausdruck, der wahr ist, ansonsten würde ich doch gar nicht dahin kommen?



  • Achso, jetzt habe ich das gesehen 😃 Kannst du mal die ganze Funktion zeigen?



  • ok, hier zumindest der Teil bis zum Programmabsturz:

    void* thread_download_parse_arcticlepage (void* arg){
    	article_view* ArticleView = (article_view*) arg;
    //MUTEX BEGIN
    	if (pthread_mutex_lock(&mutex) != 0){cout << "[FATAL] COULD NOT LOCK MUTEX";}
    
    	if (!ArticleView->get_article()->parsed_article_site){
    		ArticleView->get_StatusDisplay()->add_text ("Angebotsseite downloaden und parsen");
    		string url, localfile;
    		url = ArticleView->get_article()->url_to_auction;
    		localfile = ArticleView->get_settingsreader()->get_value("temp_download_directory") + ArticleView->get_article()->hash + ".htm";
    
    		int seconds_since_last_access = etc_lib().seconds_since_last_file_access(localfile);
    		if (seconds_since_last_access < 0 || (double) seconds_since_last_access > ArticleView->get_settingsreader()->get_dvalue("updating_article_site") * 60){
    			cout << "unlock mutex for download"<<endl;
    			if (pthread_mutex_unlock(&mutex) != 0){cout << "[FATAL] COULD NOT UNLOCK MUTEX";}
    //MUTEX END
    			cout << "start download " << url<<endl;
    			etc_lib().download_file(url, localfile);
    			cout << "finished download " << url<<endl;
    //MUTEX BEGIN
    			if (pthread_mutex_lock(&mutex) != 0){cout << "[FATAL] COULD NOT LOCK MUTEX";}
    		}
    		try{
    			string s = ArticleView->get_settingsreader()->get_value("temp_download_directory");
    			s += ArticleView->get_article()->hash + ".htm";
    			article* a = ArticleView->get_article();
    			ArticleView->get_parser()->parse_article_site(s, a);
    			ArticleView->get_article()->url_to_localimage = ArticleView->get_settingsreader()->get_value("temp_download_directory") + ArticleView->get_article()->hash + ".jpg";
    		}
    		catch (eParseException &Exception){
    			std::cout << "[PARSING ERROR] " << Exception.get_errmsg() << endl;
    		}
    ...
    

    Wie gesagt wartet einer von beiden Threads (zumindest habe ich das mit "cout-Debuggen" festgestellt) nach dem Download, der erste der fertig ist macht dann weiter und stürzt im try-Block ab.



  • Der Fehler liegt bestimmt irgendwo in ArticleView.

    Btw. als Tipp: Typen werden meist gross geschrieben und Variablen klein. Darueber hinaus ist dein Quelltext eher von schlechter Qualitaet.



  • Tut mir Leid, dass ich euch damit gernervt habe. Ich habe gerade den Fehler gefunden, er lag tatsächlich etwas tiefer im Programm, wo die Threads gestartet werden.

    Ich danke euch aber trotzdem für eure Hilfe!


Anmelden zum Antworten