如何创建一个健壮的线程安全的C++库(dll),并使其兼容处理多个并发请求?

问题描述 投票:0回答:1

我正在开发 dll WebApp 支持。 而且,我需要一些输入来使这个实现稳健。

计划的方法:

  1. 创建服务器端中间层:我们将开发一个使用 Windows DLL 的服务器端应用程序(例如,使用 .NET、Node.js 或其他环境)。
  2. Web 应用程序然后通过 API(REST、WebSocket 等)与服务器通信,服务器对 DLL 进行必要的调用。

从 .dll 公开/导出的 API 将类似于“ConvertFile(inputFile, conversionOutputFile)”。

问题: 多个浏览器有可能同时调用该 API。当多个浏览器向服务器端应用程序发送 API 请求时,会引发内存问题、资源死锁等类型的错误或使用户等待太长时间才能获得输出。

我遇到了不同的可能方法:

  • DLL 的单一实例(由所有线程共享): 确保 DLL 函数是线程安全的。 示例:使用互斥锁来同步函数调用。 尝试了这种方法,出现资源死锁错误。
  • DLL 的单独实例: 为每个线程或请求加载 DLL 的新实例。这避免了共享状态,但可能会占用资源。
  • 带有队列的工作线程: 集中式工作池逐一或按受控批次处理请求,安全地委托给 DLL。

我的想法: 优化此方法 - DLL 实例的连接池。

  1. 我们可以维护一个 DLL 实例池,可以由不同的传入请求/线程重用,而不是为每个请求加载和卸载 DLL。
  2. 当请求到达时,从池中分配一个可用的 DLL 实例。
  3. 请求处理完毕后,将实例返回到池中。
  4. 为每个新请求创建 dll 的副本,然后加载->卸载->删除新的 dll 实例。

我在“ConvertFile”API 实现中实现了基本的线程安全代码。 示例代码:

// Mutex for thread safety
static std::mutex datakitMutex;
bool ConvertFile(const std::wstring& inputFile, const std::wstring& outputFile)
{
    bool result = FALSE;
    std::lock_guard<std::recursive_mutex> lock(dllMutex);
    
    //Assume - Core logic implemented here
    //This function is expected to translate uploaded inputFile data into outputFile format.
    //Conversion process may require a few seconds to a few minutes of time to complete.
    
    return result;
}

除了上述线程安全之外,我还需要建议来实现上述问题陈述的最佳方法。

c++ multithreading dll server-side
1个回答
0
投票

对于类似的事情

bool ConvertFile(const std::wstring& inputFile, const std::wstring& outputFile);

你不需要互斥锁。

您只需确保

outputFile
尚未使用,例如通过文件锁(或简单地返回
false
,指示错误情况)。


使用互斥体来同步函数调用。

不,您不同步函数调用,您同步数据访问。 每当不同的线程访问相同的内存位置,并且当这些访问之一是写操作时,则必须进行同步(例如通过互斥体或原子存储)。


始终使用队列和列表(也称为池)。无论是内存、线程还是任务。通常,从池中获取资源(仅列表操作需要锁)并独立处理这些对象的速度非常快。完成后,通知感兴趣的人(或将其放在另一个队列中以供进一步处理),如果没有,则只需将其返回到池中(同样,仅锁定列表操作)。通过这种方式,可以避免昂贵的互斥体使用,尤其是死锁和数据竞争。

对于简单(原始)可变全局数据对象,请使用原子存储类型。


最后,一旦您拥有强大的库,请在单个进程(具有多个线程)中仅使用单个实例。请记住,加载库有其自身的成本,为什么要支付额外费用?

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.