重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这期内容当中小编将会给大家带来有关C++中怎么避免数据竞争,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
10年的疏勒网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。网络营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整疏勒建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联公司从事“疏勒网站设计”,“疏勒网站推广”以来,每个客户项目都认真落实执行。
Reason(原因)
Unless you do, nothing is guaranteed to work and subtle errors will persist.
除非你做到了,否则没有任何东西可以保证动作,微妙的错误还会继续存在。
Note(注意)
In a nutshell, if two threads can access the same object concurrently (without synchronization), and at least one is a writer (performing a non-const operation), you have a data race. For further information of how to use synchronization well to eliminate data races, please consult a good book about concurrency.
简而言之,如果两个线程可以(不进行任何同步)并发访问同一个对象,至少一个线程执行写操作(执行非常量操作),就会发生数据竞争。为了获得如何更好地使用同步以消除数据竞争的进一步信息,请查阅有关并发的经典书籍。
Example, bad(反面示例)
There are many examples of data races that exist, some of which are running in production software at this very moment. One very simple example:
有关数据竞争的例子非常多,有些就发生于正在运行的产品级软件。下面是很简单的例子:
int get_id()
{
static int id = 1;
return id++;
}
The increment here is an example of a data race. This can go wrong in many ways, including:
代码中的增量操作就是数据竞争的例子。出错的方式可以有很多种,包括:
Thread A loads the value of id, the OS context switches A out for some period, during which other threads create hundreds of IDs. Thread A is then allowed to run again, and id is written back to that location as A's read of id plus one.
线程A获取id的值之后操作系统上下文从A中退出一段时间,这时另外的线程生成了几百个ID。接着线程A继续运行,这时id重新被写入,而值是A读取的局部变量加1之后的结果。
Thread A and B load id and increment it simultaneously. They both get the same ID.
线程A和B同时获取id并加1。它们得到同样的ID。
Local static variables are a common source of data races.
局部静态变量是数据竞争的常见来源。
Example, bad(反面示例):
void f(fstream& fs, regex pattern)
{
array buf;
int sz = read_vec(fs, buf, max); // read from fs into buf
gsl::span s {buf};
// ...
auto h2 = async([&] { sort(std::execution::par, s); }); // spawn a task to sort
// ...
auto h3 = async([&] { return find_all(buf, sz, pattern); }); // spawn a task to find matches
// ...
}
Here, we have a (nasty) data race on the elements of buf (sort will both read and write). All data races are nasty. Here, we managed to get a data race on data on the stack. Not all data races are as easy to spot as this one.
这里,保存在buf中的元素会发生(严重的)数据竞争(排序既包含读操作也包含写操作)。没有哪个数据竞争是不严重的。代码中的数据竞争发生在堆栈中的数据。不是所有的数据竞争都像本例这样容易被发现。
Example, bad(反面示例):
// code not controlled by a lock
unsigned val;
if (val < 5) {
// ... other thread can change val here ...
switch (val) {
case 0: // ...
case 1: // ...
case 2: // ...
case 3: // ...
case 4: // ...
}
}
Now, a compiler that does not know that val can change will most likely implement that switch using a jump table with five entries. Then, a val outside the [0..4] range will cause a jump to an address that could be anywhere in the program, and execution would proceed there. Really, "all bets are off" if you get a data race. Actually, it can be worse still: by looking at the generated code you may be able to determine where the stray jump will go for a given value; this can be a security risk.
现在,编译器不知道val会被修改,因此编译结果很可能是一个带有五个分支的跳转表。那么一旦val的值超越了范围[0..4],就有可能调转到程序的任何位置并从那里继续执行。真的,一旦发生了数据竞争,结果会怎么样谁也不知道。实际上,还有可能更坏:通过检查生成的代码,你或许可以准确算出针对一个给定的值,程序可以跳转到什么位置。这可能成为一个安全风险。
Enforcement(实施建议)
Some is possible, do at least something. There are commercial and open-source tools that try to address this problem, but be aware that solutions have costs and blind spots. Static tools often have many false positives and run-time tools often have a significant cost. We hope for better tools. Using multiple tools can catch more problems than a single one.
有一些是可能的,至少做点什么。有些商用和开源工具试图定位这些问题,但是需要注意的是:解决方案需要成本并存在盲区。静态工具会产生很多误报,而运行时工具通常需要巨大的成本。我们希望出现更好的工具。使用多种工具会比单一工具捕捉更多的错误。
There are other ways you can mitigate the chance of data races:
存在另外的方法可以降低数据竞争的可能性:
Avoid global data
避免全局数据
Avoid static variables
避免静态数据
More use of value types on the stack (and don't pass pointers around too much)
在堆栈上更多地使用值类型(并且不要来回传递指针)
More use of immutable data (literals, constexpr, and const)
更多地使用不可修改的数据(literals, constexpr, and const)
上述就是小编为大家分享的C++中怎么避免数据竞争了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。