Сбой Bdb при одновременной записи, c linux / osx

#berkeley-db

#berkeley-db

Вопрос:

У меня возникли проблемы с bdb и там механизмами блокировки.

Следующий код приводит либо к ошибке seg, либо к тому, что выглядит как взаимоблокировка / бесконечный цикл

 #include <iostream>
#include "db_cxx.h"
#include <boost/thread.hpp>

using namespace std;

void thread_instance(Db* db, double start){
double s = start; 
double finish = start   5000;

for(int x=s; x < finish ; x  ){
Dbt key(amp;x, sizeof(double));
Dbt ddata(amp;x, sizeof(double));

db->put(NULL, amp;key, amp;ddata, 0);
}
}

int
compare_double(DB *dbp, const DBT *a,const DBT *b){
double ai, bi;

memcpy(amp;ai, a->data, sizeof(double));
memcpy(amp;bi, b->data, sizeof(double));

return (ai > bi ? 1 : ((ai < bi) ? -1 : 0));
}

int main(){
system("rm data/*");

u_int32_t env_flags = DB_CREATE | DB_INIT_MPOOL | DB_INIT_CDB;

DbEnv* env = new DbEnv(0);
env->set_cachesize(0, 2000000, 1);

u_int32_t m = 0;
env->open("data/", env_flags, 0);

Db* db = new Db(env, 0);
db->set_bt_compare(compare_double);
db->set_flags(DB_DUPSORT);
db->set_pagesize(32768);
db->set_dup_compare(compare_double);

u_int32_t oFlags = DB_CREATE;
try {
db->open(NULL, "db", NULL, DB_BTREE, oFlags, 0);

} catch (DbException amp;e) {
} catch (std::exception amp;e) {
}

vector<boost::thread*> threads;

for(int x=0; x < 3; x  ){
    threads.push_back(new boost::thread(boost::bind(amp;thread_instance, db, (x *5000))));
}

for(int x=0; x < threads.size(); x  ){
    threads[x]->join();
}
};
  

Я также пробовал DB_INIT_LOCK, но с теми же результатами.

Дорожка стека:

 Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000019
[Switching to process 34816]
0x00000001002e36a7 in __bamc_put ()
(gdb) ba
#0  0x00000001002e36a7 in __bamc_put ()
#1  0x0000000100386689 in __dbc_iput ()
#2  0x0000000100387a6c in __dbc_put ()
#3  0x0000000100383092 in __db_put ()
#4  0x0000000100397888 in __db_put_pp ()
#5  0x00000001002cee59 in Db::put ()
#6  0x0000000100001f88 in thread_instance (db=0x1007006c0, start=5000) at src/main.cpp:16
#7  0x0000000100698254 in thread_proxy ()
#8  0x00007fff80cb9456 in _pthread_start ()
#9  0x00007fff80cb9309 in thread_start ()
  

Кто-нибудь знает, что здесь может происходить?

Ответ №1:

Я бы рекомендовал проверять ошибки после db->open, печатать сообщение, если таковое имеется, вместо того, чтобы пропускать его: catch (DbException amp;e) { cerr << e.what() << endl; }

Также, похоже, вы неправильно определили флаги: требуется по крайней мере DB_THREAD, потому что вы используете его в потоках