首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在tdb中使用多个作者?

如何在tdb中使用多个作者?
EN

Stack Overflow用户
提问于 2021-07-28 00:49:13
回答 1查看 62关注 0票数 0

我正在使用tdb来尝试熟悉Linux上C语言的数据库管理。每tdb的描述

tdb是一个简单的数据库。 在概念上,它非常类似于GDBM和BSD的DB ,只不过它允许多个同时编写器,并且使用内部锁定来防止编写人员践踏彼此的。tdb也非常小。接口 该接口与gdbm非常类似,但有以下情况:

  • 不同的开放界面。tdb_open调用更类似于传统的open()
  • 无tdbm_reorganise()函数
  • 没有tdbm_sync()函数。无论如何,库中没有缓存任何操作。
  • 新增事务支持

使用tdb的一个一般规则是调用方释放任何返回的TDB_DATA结构。只需调用free(p.dptr)释放名为p的TDB_DATA返回值,这与gdbm相同。

现在我想做一个小的测试程序来测试对我的数据库的多个写连接。但失败了。

代码语言:javascript
复制
#include <tdb.h>

int main(int argc, char** argv) {
   struct tdb_context * tdb = tdb_open("test.tdb", 0, 0,
           O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);
   if(!tdb){
       printf("%s\n", tdb_errorstr(tdb));
   } else {
       printf("Database successfully opened!\n");
   }
   
   struct tdb_context * anothertdb = tdb_open("test.tdb", 0, 0,
           O_RDWR| O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);  //why does this fail?
   if(!anothertdb){
       printf("%s\n", tdb_errorstr(anothertdb));
   } else {
       printf("Another reader successfully opened!\n");
   }
   
   if(tdb_close(anothertdb)){
       printf("Error while closing database!\n");
   } else {
       printf("closing anothertdb-connection\n");
   }
   
   if(tdb_close(tdb)){
       printf("Error while closing database!\n");
   } else {
       printf("closing tdb-connection\n");
   }
return 0;
}

产出如下:

代码语言:javascript
复制
Database successfully opened!

RUN FINISHED; Segmentation fault; core dumped; real time: 240ms; user: 0ms; system: 20ms

如果我只打开到数据库的单个连接,就没有问题。如何在数据库上打开多个阅读器?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-28 01:58:08

第一个问题是在tdb_errorstring失败后调用tdb_open

代码语言:javascript
复制
if(!anothertdb){
       printf("%s\n", tdb_errorstr(anothertdb));
}

这可能并不明显,但我们有充分的理由怀疑它不能工作,因为在调用anothertdb时,tdb_errorstr肯定是NULL,假定tdb_errorstr的论点必须是指向struct tdb_context的有效指针是合理的。事实上,这是真的;实际上,tdb_errorstring做的第一件事就是试图取消引用它的参数,以提取最后的错误代码。

简而言之,无法从tdb_open失败的结果中提取自定义错误字符串;您所能做的就是对来自fopen():call perror()NULL返回所做的操作,希望errno将被设置为有意义的东西。如果这样做,您将看到一条错误消息,而不是崩溃:

代码语言:javascript
复制
$ ./tdb_test 
Database successfully opened!
open 2: Device or resource busy

库似乎有一种将tdb_open错误发送到已配置日志系统的方法,但是默认配置的日志系统只是抛出错误调用而不做任何操作。我没有阅读文档来查看是否有关于如何配置记录器的描述;您可能需要了解这一点。

顺便说一句,我不是在为这个API设计辩护。只是报告而已。

好的,接下来是您的实际问题:如何打开到TDB数据库的多个连接?答案是,你必须通过多个过程来完成这个任务。一个单独的进程可以打开任意数量的TDB,但是它只能打开其中的每一个(一次)。根据源代码中的一条注释,这是fcntl()锁定工作方式的结果,对我来说这似乎是一个合理的解释。

因此,如果您想尝试一个多读取器、多作者方案,您必须运行多个进程,或者从父进程中分送多个子进程。线程无法工作,因为同一个进程中的两个线程也不能打开相同的TDB。每个过程都是开放的。

另外,如果您选择分叉多个子进程,请记住,只需要在分叉之后调用tdb_open,因为如果您在父进程中打开一个TDB,它仍将在子进程中打开。

最后请注意,请养成将警告和错误消息写入stderr的习惯,这通常不会被缓冲,这样您在输出错误消息时就更有可能出现错误消息,而不是稍后stdio库选择刷新stdout输出缓冲区的时候。这实际上不是一个问题,但可能是这样的,因此您最好使用stderr来实现这个目的(这是它的目的,因此也就是它的名称)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68553141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档