C++多线程程序怎么理解
本篇内容主要讲解"C++多线程程序怎么理解",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"C++多线程程序怎么理解"吧!
CP.1: 设想你的代码会成为多线程程序的一部分
Reason(原因)
很难确定现在不需要并发或者将来的某个时间也不会使用。代码会被重用的。没有使用线程的库有可能被使用线程的、程序的其它部分使用。注意本准则对于功能库具有最大的紧迫性,而对于单独的应用程序就没什么紧迫性。然而,随着时间的推移,代码片段会出现在意想不到的地方。
Example, bad(反面示例)
double cached_computation(double x)
{
// bad: these statics cause data races in multi-threaded usage
static double cached_x = 0.0;
static double cached_result = COMPUTATION_OF_ZERO;
if (cached_x != x) {
cached_x = x;
cached_result = computation(x);
}
return cached_result;
}
Although cached_computation works perfectly in a single-threaded environment, in a multi-threaded environment the two static variables result in data races and thus undefined behavior.
虽然缓存计算可以在单线程环境中运行得很完美,但在多线程环境中,两个静态变量处于数据竞争状态,因此会导致无定义的行为。
Example, good(范例)
struct ComputationCache {
double cached_x = 0.0;
double cached_result = COMPUTATION_OF_ZERO;
double compute(double x) {
if (cached_x != x) {
cached_x = x;
cached_result = computation(x);
}
return cached_result;
}
};
这段代码中,缓存数据存作为ComputationCache对象的数据成员存储,而不是静态的状态数据。这个重构从根本上将决定权向上委托给调用者:单线程程序可以继续使用全局的ComputationCache实例,而多线程程序可以每个线程管理一个ComputationCache实例,或者每个上下文一个实例,这个上下文可以有多种解释。重构的函数不再试图管理cached_x的内存分配。从这个角度来讲,这算是单独责任原则的一个应用。
在这个特定的例子中,目的在于线程安全的重构同时提高了单线程环境中的重用性。不难想象单线程有可能需要两个用于程序不同部分的ComputationCache实例,而不会发生缓存数据的相互覆盖。
存在很多其他的方式,其中一个是为了在标准的多线程环境(即,使用并发的唯一形式std::thread)中运行的代码中增加线程安全处理。
Mark the state variables as thread_local instead of static.
将状态变量定义为线程内部的局部变量而不是静态变量。
Implement concurrency control, for example, protecting access to the two static variables with a static std::mutex.
实现并发控制,例如,使用静态的std::mutex保护对两个静态变量的访问。
Refuse to build and/or run in a multi-threaded environment.
拒绝在多任务环境中编译或执行代码。
Provide two implementations: one for single-threaded environments and another for multi-threaded environments.
提供两种实现:一个用于单线程环境,另一个用于多线程环境。
Exception(例外)
Code that is never run in a multi-threaded environment.
永远不会运行于多线程环境的代码。
需要小心的是:存在很多事例本来被认为永远不会运行于多线程程序的代码最后成为多线程程序的一部分,通常是几年之后。一般来讲,为这样的程序消除数据竞争会非常痛苦。因此,一旦决定代码永远不会在多线程环境中运行,应该清晰地标记出来,而且最好同时提供编译和运行时的强制机制以尽早捕捉错误的用法。
到此,相信大家对"C++多线程程序怎么理解"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!