Беркли Д.Б., Многопоточная ФАТАЛЬНАЯ ОШИБКА - PullRequest
0 голосов
/ 24 апреля 2011

Я написал программу, которая использует Беркли БД на C / C ++ как смесь. У меня есть один класс с именем bdb с этим методом.

    int open(char *db_name)
 {

  flags = DB_CREATE;
  u_int32_t envCreateFlags = DB_CREATE |
                           DB_INIT_LOCK|
                           DB_INIT_LOG|
                           DB_INIT_MPOOL|
                           DB_INIT_TXN|
                           DB_RECOVER |
                           DB_THREAD;


  ret = db_env_create(&dbenv, 0);
        dbenv->err(dbenv,ret,"err db_env_create ");         
  ret = dbenv->open(dbenv,"./",envCreateFlags,0);
       dbenv->err(dbenv,ret,"err db_env_open ");     
  ret = db_create(&dbp,dbenv, 0);
dbp->err(dbp,ret,"err db_create ");     
  ret = dbp->open(dbp,        /* DB structure pointer */
                  NULL,       /* Transaction pointer */
                  db_name, /* On-disk file that holds the database. */
                  NULL,       /* Optional logical database name */
                  DB_BTREE,   /* Database access method */
                  flags,      /* Open flags */
                  0);         /* File mode (using defaults) */

dbp->err(dbp,ret,"err dbp open  ");     


  return ret;
 };

Поэтому в следующей программе я буду использовать метод, подобный

 int getEntry( char *url ,unsigned int *fp)
 {
  DBT key, data;

   DBC *cursorp;
   dbp->cursor(dbp, NULL, &cursorp, 0); 

   memset(&key, 0, sizeof(DBT));
   memset(&data, 0, sizeof(DBT));

   key.data = fp;
   key.ulen = sizeof(unsigned int);
   key.flags = DB_DBT_USERMEM;

   data.data = url;
   data.ulen = sizeof(char) * maxUrlSize;
   data.flags = DB_DBT_USERMEM;

   ret = cursorp->c_get(cursorp, &key,&data, DB_PREV);
  if (cursorp != NULL) 
   cursorp->close(cursorp); 


  if (ret == DB_NOTFOUND)
   return -1;
}

Итак, объект создается один, а затем адрес передается нескольким потокам. все они могут одновременно получать getEntry и checkUpdate ..

результат - каждый раз, когда я получаю после запуска программы

PANIC: fatal region error detected; run recovery
PANIC: fatal region error detected; run recovery

И я получаю ошибку сегментации на линии

ret = cursorp->c_get(cursorp, &key,&data, DB_PREV);

Не знаю почему?

1 Ответ

0 голосов
/ 26 апреля 2011

Возможно, вы захотите опубликовать свой вопрос на форуме Berkeley DB на OTN.На этом форуме активно работает сообщество разработчиков приложений, инженеров поддержки и разработчиков BDB.

Вот несколько быстрых возможностей:

  • Возможно ли, что ваше приложение вызывает dbenv-> open () в каждом потоке?Это может привести к тому симптому, который вы описываете.Вы только хотите вызвать dbenv-> open один раз в начале вашего приложения.
  • Вам нужно указать DB_THREAD при открытии дескриптора базы данных.

Может быть полезна следующая документация: Глава 4 Руководства по началу работы с C ++, Пример в Руководстве по началу работы с C ++, Замечания для программистов глава в Справочном руководстве Y.

Если это не решит ваш вопрос, я рекомендую вам опубликовать сообщение на форуме Беркли, указанном выше.

...