如何在main之前预加载数据
How to preload data before main
我的目标是快速处理各种竞争条件,如果在两个不同的线程中同时调用给定的函数,这些条件可能会导致问题。我的快速解决方法是通过在main()之前调用函数来保证函数已经初始化。这是我想出的解决方案,但我觉得我很可能在重新发明轮子。MSVC2010 STL中是否已有可用选项?(还没有提升)或者,在这种情况下,是否有更好的方法可以快速处理这些问题,而不必为每个函数添加重要的线程安全代码?
template <typename T, T func>
struct PreLoaderHelper
{
PreLoaderHelper()
{
wcout << L"Preload helper constructor" << endl;
func();
}
};
template <typename T, T func>
struct PreLoader
{
static PreLoaderHelper<T, func> _helper;
};
template <typename T, T func>
PreLoaderHelper<T, func> PreLoader<T, func>::_helper;
#define PRELOAD(fn) template struct PreLoader<decltype(&fn), fn>;
void foo() { wcout << L"inside foo" << endl; }
void bar() { wcout << L"inside bar" << endl; }
vector<wstring> & foobar()
{
static vector<wstring> sPresidents;
if(sPresidents.size() == 0)
{
sPresidents.push_back(L"George Washington");
sPresidents.push_back(L"John Addams");
sPresidents.push_back(L"Thomas Jefferson");
}
return sPresidents;
}
wstring foofoo(const wstring &) { wcout << L"inside foofoo" << endl; return L"foofoo";}
PRELOAD(foo);
PRELOAD(bar);
PRELOAD(foobar);
PRELOAD(foo);
int main()
{
return 0;
}
第一个问题:你以前真的要打电话给他们吗进入main?为什么不直接把它们称为首要任务呢,在启动任何线程之前?
否则:经典的习惯用法是在初始化器中使用它们转换为静态变量。通常的方法是从构造函数;如果您有额外的数据初始化,这无疑是最好的方式。如果不是,像这样简单的东西
static bool initialized = (function(), true);
会成功的。
从形式上讲,这只能保证它们将被初始化在使用了同一翻译单元中的任何其他内容之前,但实际上,这将保证函数被调用在main之前,或者在加载DLL期间,如果它在DLL中除了带main的那个。
您可以这样做:
int dummy = (foo(), (void)0, bar(), 0);
int main()
{
// foo() and bar() have already been called
}
此外,C++11保证以下变体只会导致一次无种族的调用:
void call_foo()
{
static int dummy = (call_foo(), 0);
}
void some_thread_function() { call_foo(); }
如果您使用C++11,请记住:
- 静态函数变量初始化是线程安全的
- 您可以使用列表初始化语义
尝试:
std::vector<std::wstring>& plop1()
{
// Thread safe
// Guaranteed to be done once
// No setup required
// No cost if not used.
static std::vector<std::wstring> sPresidents =
{
L"George Washington",
L"John Addams",
L"Thomas Jefferson"
};
return sPresidents;
}
对于您的情况,我强烈建议使用关键部分进行适当的同步。进入和退出关键部分不会添加太多代码,并且可以优雅地处理这种情况。
如果您不想继续使用在main()之前初始化函数的原始方法,可以使用全局变量初始化,因为它发生在main函数调用之前。有一篇关于这种方法的好文章
http://blog.fishingcactus.com/index.php/2009/01/28/fixing-c-static-and-global-variable-initialization/#sthash.pmBtrYD8.dpbs
- 使用ifstream从DAT文件加载数据
- SqlDataAdapter 未加载数据表 - C++
- C ,MySQL API加载数据本地
- 使用提升库在队列和堆栈数据结构上保存和加载数据时出错
- 使用 fstream 从文件加载数据
- 从文件加载数据
- 将错误处理添加到加载数据的函数(但有时还需要使用默认值)
- C#从文件加载数据并分类为数组
- 保存/加载C++数据时出错
- C++简体版链表,当我加载数据以创建链表并输入更多数据时,似乎存在差距
- 我无法加载数据文件,总是无法打开它
- 从C++模拟中保存和加载数据的有效方法
- 快板 5 加载数据文件
- 通过C++虚幻引擎改进加载数据
- 使用套接字从页面加载数据
- 创建缓冲区以加载数据时出错
- 使用 boost 序列化到磁盘后无法加载数据
- 从C++中的CSV文件读取和加载数据时出现问题
- 如何在运行时通过插件机制动态加载数据类型
- 保存和加载数据C++