【问题标题】:Is it bad practice to create a thread in a shared library?在共享库中创建线程是不好的做法吗?
【发布时间】:2014-12-04 21:03:32
【问题描述】:

我正在创建一个共享库,其中一个类在其构造函数中创建一个线程,该线程运行它直到调用析构函数。这个类的所有方法都是线程安全的。像这样的:

class NetworkRPCConnection {
  std::thread t;
public:
  NetworkRPCConnection() : t([](){maintain_connection();}) {}
  ~NetworkRPCConnection(){close_connection(); t.join();}
}

这很好用,但是在共享库中创建线程是不好的做法吗?是否值得在 API 文档中提及,还是隐藏此实现细节更好?

【问题讨论】:

  • 一定要在 API 中记录。
  • 好吧,我读过的所有书都说,实现细节应该隐藏在文档之外。如果库使用线程,为什么开发人员想知道?
  • 开发人员需要知道,因为他们可能会使用线程,如果有其他东西在使用它们,那么对资源的压力就会更大。此外,线程通常需要特殊的构建配置和选项才能合并到构建系统中。
  • @GamePad64 你所有的书都错了。好吧,他们是部分错误的。隐藏实现细节时应该使用您的判断,而不是随意隐藏它们。例如,我肯定很想知道您的模块需要 20 GB 的内存。在这种情况下,我会从线程资源的角度感兴趣。
  • 如果库使用线程,我可能需要小心更改全局语言环境,或安装信号处理程序,或调用写入静态数据的不可重入函数,例如 gmtime

标签: c++ multithreading shared-libraries


【解决方案1】:

一般来说,最好避免在共享库中创建线程,但在某些情况下是可以的 - 但在这些情况下,您确实需要在 API 中记录它。

您需要记录它的原因是线程可以以难以预测的方式与某些操作交互 - 特别是 fork() 和信号;这使得将线程作为实现细节完全“隐藏”是不可能的,因为库用户需要知道它。

至于为什么最好不要创建线程:通常库的用户对他们的线程模型有更好的了解 - 例如,他们可能已经有一个可以完成工作的线程,所以只创建另一个产生额外的开销(并限制它们的实现)。但是如果你非常了解库用户的需求,并且知道需要一个独占线程,并且可以处理线程生命周期的所有方面——那么你自己创建和管理线程可能是可以的——但是,作为上面提到的,你肯定需要记录它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 2019-04-19
    • 1970-01-01
    相关资源
    最近更新 更多