Breakermind Temat założony przez niniejszego użytkownika |
C++ Thread worker and mysql connections » 2017-10-11 13:42:49 Dzień dobry, jaka może być przyczyna zatrzymania się tredów w programie?
Mam trzy tredy odpalane na początku programu nastepnie mam petlę while wyświetlającą tekst (while(1){cout << "main text";}). Po jakimś czasie (kilku minut) pętle z tread workerów przestają działać, gdzie szukać przyczyny (w tredworkerach wszystko jest w petli while(1){ cout << "tekst tread"; } i nie ma breaków). Dodałem dodatkowo fork() w tred worker lecz nie poprawiło to sytuacji.
Pozdrawiam |
|
Breakermind Temat założony przez niniejszego użytkownika |
» 2017-10-11 20:29:15 Witam, wyskakuje jakiś error: *** Error in `./start': free(): invalid pointer: 0x00007f32e1fb4eb8 *** Kompiluję: g++ -o start main.cpp -std=c++11 -pthread -L/usr/include/mysql -lmysqlclient -I/usr/include/mysql Gdzie coś pomieszałem?
#include <iostream> #include <thread>
#include <unistd.h>
#include <mysql.h>
#include <vector>
using namespace std;
vector < vector < string >> select() { MYSQL * connect, mysql; MYSQL_RES * result; int query_state; connect = mysql_init( NULL ); if( !connect ) { cout << "MySQL Initialization failed"; } connect = mysql_real_connect( connect, "localhost", "root", "toor", "SMTP", 3306, NULL, 0 ); if( connect ) { cout << "connection Succeeded\n"; } else { cout << "connection failed"; } MYSQL_RES * res_set; MYSQL_ROW row; MYSQL_FIELD * field; mysql_query( connect, "select id,email_to,resendtime,send from messages;" ); unsigned int i = 0; res_set = mysql_store_result( connect ); unsigned int numrows = mysql_num_rows( res_set ); int num_fields = mysql_num_fields( res_set ); try { while((( row = mysql_fetch_row( res_set ) ) != NULL ) ) { cout << "Row " << row[ i ] << " " << row[ i + 1 ] << " " << row[ i + 2 ] << endl; } } catch( std::exception & e ) { cout << "Error pointer " << endl; } mysql_free_result( res_set ); mysql_close( connect ); }
void foo() { while( 1 ) { cout << "Hello from thread" << endl; sleep( 1 ); select(); } }
void bar( int x ) { while( 1 ) { cout << "Hello from thread " << x << endl; sleep( 1 ); } }
int main() { std::thread t1( foo ); std::thread t2( bar, 0 ); std::cout << "main, foo and bar now execute concurrently...\n" << endl; while( 1 ) { std::cout << "Main thread looooop \n"; sleep( 1 ); } return 0; }
Chodzi mi o pobieranie danych z tabelki z bazy danych w osobnym threadzie? |
|
Monika90 |
» 2017-10-11 20:33:57 W funkcji select zapomniałeś o instrukcji return. |
|
Breakermind Temat założony przez niniejszego użytkownika |
» 2017-10-11 20:42:29 Dzięki! Hehehehe ale banał :). A już miałem pół serwera wyrzucać :D. Gdzie jakiś dobre ide do c++ na linuxa co by mi te wszystkie "debilizmy" wyświetlało i żebym nie musiał jak "moron" z konsoli szukać (jakiś movie najlepiej :) z youtu.be)? Naprawiona część: vector < vector < string >> select( std::string txt ) { MYSQL * connect, mysql; MYSQL_RES * result; int query_state; connect = mysql_init( NULL ); if( !connect ) { cout << "MySQL Initialization failed"; } connect = mysql_real_connect( connect, "localhost", "root", "toor", "BreakermindSMTP", 3306, NULL, 0 ); if( connect ) { cout << "connection Succeeded\n"; } else { cout << "connection failed"; } vector < vector < string >> messages; MYSQL_RES * res_set; MYSQL_ROW row; MYSQL_FIELD * field; mysql_query( connect, "select id,email_to,resendtime,send from messages;" ); unsigned int i = 0; res_set = mysql_store_result( connect ); unsigned int numrows = mysql_num_rows( res_set ); int num_fields = mysql_num_fields( res_set ); try { while((( row = mysql_fetch_row( res_set ) ) != NULL ) ) { cout << txt << " " << row[ i ] << " " << row[ i + 1 ] << " " << row[ i + 2 ] << endl; vector < string > msg; msg.push_back( row[ i ] ); msg.push_back( row[ i + 1 ] ); msg.push_back( row[ i + 2 ] ); messages.push_back( msg ); } } catch( std::exception & e ) { cout << "Error pointer " << endl; } mysql_free_result( res_set ); mysql_close( connect ); return messages; }
|
|
mokrowski |
» 2017-10-11 21:16:28 To nie jest kwestia IDE. Dodaj do wywołania kompilatora:
-Wall -Wextra -pedantic
.. i w dowolnym IDE takie błędy będziesz miał zgłaszane. |
|
Breakermind Temat założony przez niniejszego użytkownika |
» 2017-10-12 09:40:33 Dzięki, działał całą noc ten programik z tredami i się nie wysypał (o dziwo, dodam resztę i zobaczę co dalej). Na Qt mi się wyświetlają błędy w netbean i eclipse zresztą też ;). Trochę tylko bez sensu że warningi wysypują program po kompilacji (Segmentation fault). Pozdrawiam
|
|
Breakermind Temat założony przez niniejszego użytkownika |
» 2017-10-12 11:20:44 Jak pobrać z osobnych tredów z tabeli(baza danych) rekordy nie powtarzając ich tzn. jeżeli pierwszy thread odczytał rekord(1) i go zaktualizował to inny tread powinien już pobrać rekord następny i dokonać aktualizacji)? Używam obecnie transakcji lecz niestety tredy pobierają czasami ten sam rekord, dlaczego się tak dzieje (Ustawiony mam silnik InnoDB na bazie danych mariadb)? A kiedyś czytałem że InnoDB blokuje poszczególne rekordy (linje) tabeli, czyli nie powinno się tak dziać. Można gdzieś pozmieniać priorytety wykonywanych zapytań lub ustawić kolejkowanie zapytań na bazie danych, jeżeli tak to gdzie i jak to zrobić? Klasa wygląda tak (może gdzieś coś poprawić trzeba): plik db.cpp #include "db.h"
DB::DB() { }
bool DB::Connect( string host = "localhost", string user = "root", string pass = "toor", string db = "BreakermindSMTP", int port = 3306 ) { connect = mysql_init( NULL ); if( !connect ) { cout << "MySQL Initialization failed"; return 0; } connect = mysql_real_connect( connect, host.c_str(), user.c_str(), pass.c_str(), db.c_str(), port, NULL, 0 ); if( connect ) { cout << "Connection Succeeded\n"; return 1; } else { cout << "Connection failed"; return 0; } }
vector < vector < string >> DB::Select( string txt = "Row " ) { vector < vector < string >> messages; MYSQL_RES * res_set; MYSQL_ROW row; mysql_autocommit( connect, false ); mysql_query( connect, "LOCK TABLES messages WRITE;" ); unsigned long trID =( unsigned long ) mysql_thread_id( connect ); cout << "MySQL Thread ID " << trID << endl; int err = mysql_query( connect, "SELECT id,email_to,send,resendtime,email_subject FROM messages WHERE send > 0 AND send < 100 AND resendtime < NOW() LIMIT 2;" ); if( err ) { fprintf( stderr, "%s\n", mysql_error( connect ) ); } unsigned int i = 0; res_set = mysql_store_result( connect ); try { while((( row = mysql_fetch_row( res_set ) ) != NULL ) ) { cout << txt << " " << row[ i ] << " " << row[ i + 1 ] << " " << row[ i + 2 ] << " " << row[ i + 3 ] << " " << row[ i + 4 ] << endl; char query[ 500 ]; sprintf( query, "UPDATE messages SET send=send+1,resendtime=DATE_ADD(NOW(), INTERVAL 5 MINUTE) WHERE id=%i;", atoi( row[ i ] ) ); cout << "Query: " << query << endl; int err = mysql_query( connect, query ); if( err ) { fprintf( stderr, "%s\n", mysql_error( connect ) ); } vector < string > msg; msg.push_back( row[ i ] ); msg.push_back( row[ i + 1 ] ); msg.push_back( row[ i + 2 ] ); messages.push_back( msg ); } } catch( std::exception & e ) { cout << "Error pointer " << endl; } mysql_query( connect, "UNLOCK TABLES;" ); mysql_free_result( res_set ); mysql_close( connect ); return messages; }
plik db.h #ifndef DB_H #define DB_H
#include <iostream> #include <vector> #include <string>
#include "mysql.h"
using namespace std;
class DB { public: MYSQL * connect; DB(); bool Connect( string host, string user, string pass, string db, int port ); vector < vector < string >> Select( string txt ); };
#endif
UPDATE: Doczytałem i po testowałem i dodałem: mysql_query( connect, "LOCK TABLES messages WRITE;" ); .... mysql_query( connect, "UNLOCK TABLES;" );
Zamiast transakcji i działa. |
|
Breakermind Temat założony przez niniejszego użytkownika |
» 2017-10-12 11:34:45 Jak przechwycić z c++ mysql error? Np. gdy ustawię na bazie danych za małą liczbę możliwych połączeń to powyższy program się zatrzymuje z błędem (Segmentation fault)? int err = mysql_query( connect, "SELECT id,email_to,send,resendtime,email_subject FROM messages WHERE send > 0 AND send < 100 AND resendtime < NOW() LIMIT 1;" ); if( err ) { fprintf( stderr, "%s\n", mysql_error( connect ) ); }
Lub jak zmusić program do ciągłego wykonywania się i nie zwracania uwagi na błędy? while( 1 ) { try { .... } catch( std::exception & e ) { cout << "# ERR: SQLException in " << __FILE__; cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl; cout << "# ERR: " << e.what(); } }
|
|
« 1 » 2 3 |