【发布时间】:2018-08-05 08:05:44
【问题描述】:
我的 API 在自己的线程中计算一些数据:
/*** API is running in its own thread ***/
class API {
public:
std::shared_ptr<Data> retrieveData() { return mData; }
private:
std::shared_ptr<Data> mData;
std::mutex mDataMutex;
void run () {
std::thread t([](){
while (!exitApi) {
mDataMutex.lock();
updateData(mData);
mDataMutex.unlock();
});
t.join();
}
};
使用我的 API 的应用程序将在另一个线程中检索共享数据:
/*** Application is running in another thread ***/
class Application {
private:
Api mApi;
void run () {
std::thread t([](){
while (!exitApp) {
std::shared_ptr<Data> data = mApi.retrieveData();
/* API thread can update the data while the App is using it! */
useData(data);
});
t.join();
}
如何设计我的 API 以使应用程序开发人员在检索数据时不会陷入困境?我能想到三个选项,但不喜欢其中任何一个:
- API 将返回所有数据的副本,而不是共享指针。但是,数据量可能会变得非常大,因此应避免复制。
- API 在将数据交给应用程序时会锁定数据,应用程序需要在执行所有计算后明确要求 API 再次解锁。即使正确记录,这也很容易出现死锁。
- 当 API 将数据交给应用程序
retrieveData时,也会返回一个已经锁定的std::unique_lock。一旦应用程序使用完数据,它必须解锁unique_lock。这可能不太容易出错,但对于应用程序开发人员来说仍然不是很明显。
有没有更好的选择来设计尽可能对开发人员友好的 API(在现代 C++11 及更高版本中)?
【问题讨论】:
标签: c++ multithreading c++11 c++17 api-design