Berkeley DB,多线程致命错误

发布于 2024-11-03 06:27:43 字数 2151 浏览 2 评论 0原文

我编写了一个程序,它混合使用了 C/C++ 中的 Berkeley DB。 我有一个名为 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);

我不知道为什么?

I wrote a program that uses the Berkeley DB in C/C++ like a mix.
I have one class called bdb with this method.

    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;
 };

So next in the program I will use a method like

 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;
}

So, the object is created ones and than the adress is given to the multiple threads.
they all to getEntry and checkUpdate maybe on the same time..

the result is every time I get after the start of the program

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

And I get a Segmentation fault on the line

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

I don't know why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

阳光下的泡沫是彩色的 2024-11-10 06:27:43

您可能需要考虑将问题发布到 OTN 上的 Berkeley DB 论坛。有一个由应用程序开发人员、支持工程师和 BDB 开发人员组成的活跃社区,他们在该论坛上进行互动。

以下是一些快速的可能性:

  • 您的应用程序是否有可能在每个线程中调用 dbenv->open() ?这往往会产生您所描述的症状。您只需在应用程序开始时调用 dbenv->open 一次。
  • 打开数据库句柄时需要指定DB_THREAD。

以下文档可能有用:《C++ 入门指南》的 第 4 章C++ 入门指南中的示例程序员注释< /a> 参考指南 Y 中的章节。

如果这不能解决您的问题,我鼓励您在上面列出的 Berkeley DB 论坛上发帖。

You might want to consider posting your question to the Berkeley DB Forum on OTN. There is an active community of application developers, support engineers and BDB developers who interact on that forum.

Here are a couple of quick possibilities:

  • Is it possible that your application is calling dbenv->open() in every thread? That would tend to produce the symptom that you describe. You only want to call dbenv->open once at the beginning of your application.
  • You need to specify DB_THREAD when you open the database handle.

The following documentation may be useful: Chapter 4 of the C++ Getting Started Guide, the Example in the C++ Getting Started Guide, the Programmer Notes chapter in the Reference GuideY.

If this doesn't resolve your question, I'd encourage you to post to the Berkeley DB forum listed above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文