【问题标题】:Implementing multithreaded application under CC下实现多线程应用
【发布时间】:2011-07-25 07:40:25
【问题描述】:

我正在实现一个像 MySQL 这样的小型数据库。它是一个更大项目的一部分。

现在我已经设计了核心数据库,我的意思是我已经实现了一个解析器,我现在可以在我的数据库上执行一些基本的 sql 查询。它可以存储、更新、删除和检索文件中的数据。作为现在它很好..但是我想在网络上实现这个..

我希望多个用户能够同时访问我的数据库服务器并对其执行查询...我在 Linux 下工作,所以现在不存在可移植性问题..

我知道我需要使用 Sockets,这很好。我也知道我需要使用像线程池这样的概念,我将被要求最初创建最大数量的线程,然后为每个客户端请求唤醒一个线程并将其分配给客户端..

至于现在我无法弄清楚的是如何将所有这些实际捆绑在一起..我应该在哪里实现多线程..在客户端/服务器端。?我的解析器将如何配置为分别从每个客户端获取输入?(我认为主要是通过文件?)

如果有人知道我如何实现这个,请告诉我,因为我被困在这个项目中......

谢谢.. :)

【问题讨论】:

  • 只是好奇;你为什么不使用SQLite
  • 可能是一个学习数据库或他希望进一步学习的家庭作业数据库。
  • @sixletters: 不是作业.. 我正在写一篇论文.. 实现在不受信任的服务提供商处存储数据的存储机制..
  • @darioo:我没有使用 SQLite,因为我自己实现了一个基本数据库,这已经完成..

标签: c linux multithreading sockets client-server


【解决方案1】:

如果您还没有,请查看Beej's Guide to Network Programming,了解一些套接字编程。

接下来,我将使用他的example of a stream client and server,并将其用作单线程查询系统。完成此操作后,您需要选择是实际使用线程还是使用select()。我的直觉是,您的磁盘数据库尚不支持并行写入(可能是读取),因此对于初学者来说,单服务器线程服务请求可能是您的最佳选择!

在多客户端模型中,您可以使用简单的每个套接字的客户端信息哈希表,并在处理他们的查询时立即返回任何结果。一旦您开始使用网络和数据库查询进行线程化,它就会变得非常复杂。因此,从单个客户端开始工作,为多个客户端添加轮询,然后开始阅读和处理线程(可能使用pthreads)客户端-服务器模型。

【讨论】:

  • @sixletters:是的,到目前为止,我主要关心的是让网络正常运行,然后我可能会考虑添加功能,例如多个客户端,然后是多个访问,然后在相同的上下文中读取/write 冲突处理..现在我正在尝试使用单个客户端代码作为启动器..感谢您的解决方案,它有帮助.. :)
  • @pratik:不客气,先生。 pthread 库包含一个读写锁实现,如果您添加线程,这可能是一种向服务器添加多个读取器/写入器的简单方法。
【解决方案2】:

服务器端,因为它是唯一可以理解信息的人。您需要设计锁或提出自己的模型,以确保修改/编辑不会影响服务对象。

【讨论】:

    【解决方案3】:

    作为多线程的替代方案,您可以考虑基于事件的单线程方法(例如使用 poll 或 epoll)。 redis 就是一个使用这种方法的非常快速(非 SQL)数据库的示例。

    这种设计有两个明显的缺点:您只使用一个 CPU 内核,并且冗长的查询会在很长一段时间内阻塞其他客户端。但是,如果查询速度相当快,没有人会注意到。

    另一方面,单线程设计具有自动序列化请求的优势。没有歧义,没有锁定需求。在读取(或另一次写入)之间不能有写入,它就是不会发生。
    如果您没有像数据库中内置的健壮、工作 MVCC 之类的东西(或者至少正在使用它),那么知道您不必担心可能是一个巨大的优势。并发读取不是问题,但并发读取和写入是。

    或者,您可以考虑在一个线程中执行输入/输出和语法检查,并在另一个线程中运行实际查询(通过队列传递的查询)。这也将消除同步问题,并且至少会提供一些延迟隐藏和一些多核。

    【讨论】:

    • 是的,实际上我现在对 MVCC 并不太在意,而且我的数据库代码中也没有。现在我认为你提到在一个线程和语法中运行实际查询会很好签入另一个...关于基于事件的我正在调查它..可能它可以达到目的..
    • 没有 MVCC,你必须使用读写锁。天真的实现(数据库级或表级锁定)这将否定多线程的大部分(如果不是全部)好处,除非您主要读取很少更新。行级锁定更好,但显然也更麻烦(而且,也不是灵丹妙药)。因此,在这种情况下,将所有内容序列化确实可以省去一些麻烦。您是否已经在使用 Boost?如果你这样做了,你可以研究 asio 来寻找一个无需额外成本的可移植解决方案(虽然手动编码 epoll 真的很容易......唯一的缺点是它不可移植)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多