您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關C++中怎么避免數據競爭,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
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<double, max> buf;
int sz = read_vec(fs, buf, max); // read from fs into buf
gsl::span<double> 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++中怎么避免數據競爭了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。