线程数据封装最佳实践

Thread data encapsulation best practices

本文关键字:最佳 数据封装 线程      更新时间:2023-10-16

我有一个问题,在这种情况下如何优雅地封装数据。假设我们想做一些可以从互联网异步下载图像的类。让我们有解锁方法:

void download(string url)

此方法将创建线程并开始下载,然后调用回调:

void callback(char* data)

什么是最好的:为下载器中的数据分配内存还是从下载器类中分配内存?在第一种情况下,我们需要复制回调中返回的数据,如果数据很大 - 它不好,否则我们将在 Downloader 类中分配内存并将其释放到其他地方。在第二种情况下,我们需要为数据分配内存,并将其作为下载方法中的参数传递:

char *data = new char[DATA_SIZE];
downloader.download(url, data);

但是我们如何保护这些分配的数据在下载线程使用时不从可调用线程更改它。我认为有某种方法可以使它在可调用线程中不同步,从而使此逻辑对客户端不可见。

希望你把我的想法弄对

一些C++标准库类可能会很好。

std::future<std::vector<unsigned char>> download(std::string url) {
    std::promise<std::vector<unsigned char>> promise;
    std::future<std::vector<unsigned char>> future = promise.get_future();
    //I'm like 99% certain that both promise and future ref-count their shared state
    //so it's probably safe to move and later even delete the promise object.
    func_which_begins_asynchronous_process(url, std::move(promise));
    return future;
}
void callback(std::vector<unsigned char> data, std::promise<std::vector<unsigned char>> promise) {
    promise.set_value(std::move(data));
}
int main() {
    auto future = download("google.com");
    //Do whatever
    std::vector<unsigned char> result = future.get();
    //Do whatever
    return 0;
}

这既可以使代码易于推理,又可以可靠地处理您在原始帖子中讨论的"指针所有权"问题。

我不知道您的代码的确切语义/要求,所以我的代码不会"按原样"在您的解决方案中工作,但这应该可以让您很好地了解解决您的问题的范式类型。