如何解决在处理加载程序线程和大量数据时,扩大放置关键部分的位置
我已经阅读了有关该主题的教程,并观看了有关该主题的YouTube视频,我想我理解为什么使用它们的原因。使用它们的原因很多,但其中之一是因为现代的多核CPU具有内部缓存来提高性能(L1和L2)。如果一个内核读取了旧信息,如果它们在与该内核相关联的高速缓存中存储了旧内存,则可能会读取这些信息。添加关键部分会强制刷新这些缓存。
我正试图加深我对该关键部分的位置的理解,我觉得大多数在线信息来源实际上都无法很好地解释。这就是为什么我要问你们这里的专家! :)
让我们举一个简短的例子:
#include <iostream>
#include <thread>
#include <mutex>
#include <list>
static constexpr auto OneMegabyte = 1 * 1024 * 1024;
struct Result
{
char data[OneMegabyte];
};
std::mutex mutex;
std::list<Result*> results;
void write_lots_of_data(Result* result)
{
auto f = fopen("large_file.txt","rb");
fread(result->data,OneMegabyte,1,f);
fclose(f);
}
void read_lots_of_data(Result* result)
{
//
}
void thread()
{
auto result = new Result();
// Writes one megabyte of data from somewhere into Memory::values
write_lots_of_data(result);
std::lock_guard<std::mutex> l(mutex);
results.push_back(result);
}
int main(int argc,char** argv)
{
std::thread t(&thread);
while (true)
{
std::lock_guard<std::mutex> l(mutex);
if (results.empty())
continue;
auto first_result = results.begin();
read_lots_of_data(*first_result);
results.erase(first_result);
break;
}
return 0;
}
可以防止同时读取和写入对results
的访问权限-据我所知。但是放入results
列表中的实际内存又如何呢?为了安全起见,我是否必须将关键部分放在write_lots_of_data
方法之前?是否足以安全地保护results
列表?
解决方法
您的验证码是正确的。
互斥锁保护列表,而不保护列表节点包含的数据。因此,正如您所写,将数据填充到Result结构中是不受保护的,不需要保护。
阅读时,只有列表需要保护。读取结果不需要保护。您的代码应按书面形式工作。可以通过一种方法进行改进:
Result* get_result()
{
std::lock_guard<std::mutex> l(mutex);
if (not results.empty())
{
Result* first_result = results.front();
results.pop_front();
return first_result;
}
return nullptr;
}
int main(int argc,char** argv)
{
std::thread t(&thread);
while (true)
{
Result* first_result = get_result();
if (first_result)
{
read_lots_of_data(first_result);
delete first_result;
}
}
return 0;
}
将锁限制为仅在列表上操作将有助于提高性能和可读性。读者将意识到,只有列表被锁定,而不是结果的读取操作。
在深入之前,请考虑在代码中也使用std::unique_ptr<Result>
,而不要使用new / delete。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。