MySQLe를 임베디드 백엔드로 사용하는 프로그램을 작성 중입니다. 데이터베이스 라이브러리는 "도메인"이라는 오브젝트가 소유합니다. 이 도메인 개체는 주 스레드 내에서 실행됩니다.다중 스레드 환경에서 MySQL Embedded을 사용하는 방법은 무엇입니까?
프로그램은 XML-RPC 서버 (boost :: thread 및 xmlrpc_c :: serverAbyss)를 실행하는 다른 스레드를 시작합니다. Domain 객체에 링크됩니다.
는 XML-RPC 서버가 도메인 객체가 SQL 쿼리에게 프로그램이 충돌을 실행합니다
:Program received signal: “EXC_BAD_ACCESS”.
[Switching to process 73191]
[Switching to process 73191]
Xcode could not locate source file: regex.cpp (line: 74)
마스터 스레드가 SQL 프로그램이 계속 실행 쿼리를 실행하는 도메인 객체의 메소드를 호출
./*
* Ports listening
*
* - create a Rpc_Server object
* - create a dedicated thread
*/
Rpc_Server server(&domain, &conf_params, &router);
boost::thread server_thread(boost::bind(&Rpc_Server::run, &server)); // This thread makes the server crash
/*
* Domain routine
*
* - Check for ready jobs every minute
*/
while (1) {
v_jobs jobs = domain.get_ready_jobs(conf_params.get_param("node_name")); // This method does NOT make the server crash
sleep(60);
}
도메인 개체의 메서드와 데이터베이스 개체의 메서드는 모두 다중 액세스를 방지하기 위해 뮤텍스를 잠급니다.
bool Mysql::execute(const std::string* query) {
MYSQL_RES* res;
MYSQL_ROW row;
if (query == NULL)
return false;
this->updates_mutex.lock();
std::cout << query->c_str() << std::endl;
if (mysql_query(this->mysql, query->c_str()) != 0) {
std::cerr << query << std::endl << mysql_error(this->mysql);
UNLOCK_MUTEX;
return false;
}
res = mysql_store_result(this->mysql);
if (res)
while ((row = mysql_fetch_row(res)))
for (uint i=0 ; i < mysql_num_fields(res) ; i++)
std::cout << row[i] << std::endl;
else
if (mysql_field_count(this->mysql) != 0) {
std::cerr << "Erreur : " << mysql_error(this->mysql) << std::endl;
mysql_free_result(res);
this->updates_mutex.unlock();
return false;
}
mysql_free_result(res);
this->updates_mutex.unlock();
return true;
}
bool Domain::add_node(const std::string* running_node, const std::string* n, const int* w) {
std::string query;
this->updates_mutex.lock();
query = "START TRANSACTION;";
if (this->database.execute(&query) == false) {
this->updates_mutex.unlock();
return false;
}
query = "REPLACE INTO node (node_name,node_weight) VALUES ('";
query += n->c_str();
query += "','";
query += boost::lexical_cast<std::string>(*w);
query += "');";
if (this->database.execute(&query) == false) {
query = "ROLLBACK;";
this->database.execute(&query);
this->updates_mutex.unlock();
return false;
}
query = "COMMIT;"
if (this->database.execute(&query) == false) {
this->updates_mutex.unlock();
return false;
} else
this->updates_mutex.unlock();
return true;
}
MySQLe가 생성됩니다
bool Mysql::prepare(const std::string* node_name, const std::string* db_skeleton) {
static char* server_args[] = {"this_program","--datadir=."};
static char* server_groups[] = {"embedded","server","this_program_SERVER",(char *)NULL};
std::string query("CREATE DATABASE IF NOT EXISTS ");
// DB init
if (mysql_library_init(sizeof(server_args)/sizeof(char *), server_args, server_groups))
std::cerr << "could not initialize MySQL library" << std::endl;
std::cout << "mysql init..." << std::endl;
if ((this->mysql = mysql_init(NULL)) == NULL)
std::cerr << mysql_error(this->mysql) << std::endl;
if (! mysql_thread_safe()) {
std::cerr << "MySQL is NOT theadsafe !" << std::endl;
return false;
}
mysql_options(this->mysql, MYSQL_READ_DEFAULT_GROUP, "embedded");
mysql_options(this->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
mysql_real_connect(this->mysql, NULL, NULL, NULL, NULL, 0, NULL, 0);
// Creates the schema
query += this->translate_into_db(node_name);
query += ";";
if (this->execute(&query) == false)
return false;
// Creates the schema
query = "CREATE SCHEMA IF NOT EXISTS ";
query += this->translate_into_db(node_name);
query += " DEFAULT CHARACTER SET latin1;";
this->execute(&query);
// Uses it
query = "USE " + this->translate_into_db(node_name) + ";";
this->execute(&query);
// Loads the skeleton from file
return this->load_file(db_skeleton->c_str());
}
잘못 어딘가에을 있습니까? 나에게 보여줄 수있는 예가 있습니까?