<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          C++核心準(zhǔn)則CP.2:避免數(shù)據(jù)競爭?

          2035289d6888971e63abc6c1ff3bd80e.webp

          CP.2: Avoid data races

          CP.2:避免數(shù)據(jù)競爭


          Reason(原因)

          Unless you do, nothing is guaranteed to work and subtle errors will persist.

          除非你做到了,否則沒有任何東西可以保證動作,微妙的錯誤還會繼續(xù)存在。


          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.

          簡而言之,如果兩個線程可以(不進(jìn)行任何同步)并發(fā)訪問同一個對象,至少一個線程執(zhí)行寫操作(執(zhí)行非常量操作),就會發(fā)生數(shù)據(jù)競爭。為了獲得如何更好地使用同步以消除數(shù)據(jù)競爭的進(jìn)一步信息,請查閱有關(guān)并發(fā)的經(jīng)典書籍。


          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:

          有關(guān)數(shù)據(jù)競爭的例子非常多,有些就發(fā)生于正在運(yùn)行的產(chǎn)品級軟件。下面是很簡單的例子:

          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:

          代碼中的增量操作就是數(shù)據(jù)競爭的例子。出錯的方式可以有很多種,包括:

          • 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的值之后操作系統(tǒng)上下文從A中退出一段時間,這時另外的線程生成了幾百個ID。接著線程A繼續(xù)運(yùn)行,這時id重新被寫入,而值是A讀取的局部變量加1之后的結(jié)果。

          • 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.

          局部靜態(tài)變量是數(shù)據(jù)競爭的常見來源。


          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 h1 = async([&] { sort(std::execution::par, s); }); // spawn a task to sort
          // ...
          auto h2 = 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中的元素會發(fā)生(嚴(yán)重的)數(shù)據(jù)競爭(排序既包含讀操作也包含寫操作)。沒有哪個數(shù)據(jù)競爭是不嚴(yán)重的。代碼中的數(shù)據(jù)競爭發(fā)生在堆棧中的數(shù)據(jù)。不是所有的數(shù)據(jù)競爭都像本例這樣容易被發(fā)現(xiàn)。


          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.

          現(xiàn)在,編譯器不知道val會被修改,因此編譯結(jié)果很可能是一個帶有五個分支的跳轉(zhuǎn)表。那么一旦val的值超越了范圍[0..4],就有可能調(diào)轉(zhuǎn)到程序的任何位置并從那里繼續(xù)執(zhí)行。真的,一旦發(fā)生了數(shù)據(jù)競爭,結(jié)果會怎么樣誰也不知道。實(shí)際上,還有可能更壞:通過檢查生成的代碼,你或許可以準(zhǔn)確算出針對一個給定的值,程序可以跳轉(zhuǎn)到什么位置。這可能成為一個安全風(fēng)險。


          Enforcement(實(shí)施建議)

          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.

          有一些是可能的,至少做點(diǎn)什么。有些商用和開源工具試圖定位這些問題,但是需要注意的是:解決方案需要成本并存在盲區(qū)。靜態(tài)工具會產(chǎn)生很多誤報,而運(yùn)行時工具通常需要巨大的成本。我們希望出現(xiàn)更好的工具。使用多種工具會比單一工具捕捉更多的錯誤。

          There are other ways you can mitigate the chance of data races:

          存在另外的方法可以降低數(shù)據(jù)競爭的可能性:

          • Avoid global data

          • 避免全局?jǐn)?shù)據(jù)

          • Avoid?static?variables

          • 避免靜態(tài)數(shù)據(jù)

          • 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)

          • 更多地使用不可修改的數(shù)據(jù)(literals,?constexpr, and?const)


          原文鏈接

          https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#cp2-avoid-data-races




          覺得本文有幫助?請分享給更多人。

          關(guān)注微信公眾號【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!

          面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>


          瀏覽 39
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费操比视频 | 国内自拍夫妻视频 | 欧美视频天天干 | 精品久久久久不卡 | 日本激情视频小说 |