成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go開發競態檢測科普文

開發 前端
本篇主要介紹了一些術語,引用了一條規則:凡是多線程對共享變量涉及到寫操作,都要考慮使用原子操作。

一、名詞解析

1、data race: Any race is a bug

定義: ①多個線程(協程)對于同一個變量、②同時地、③進行讀/寫操作、并且④至少有一個線程進行寫操作。(也就是說,如果所有線程都是只進行讀操作,那么將不構成數據爭用)

后果: 如果發生了數據爭用,讀取該變量時得到的值將變得不可知(根據內存模型),使得該多線程程序的運行結果將完全不可預測,有一定可能會導致直接崩潰。

如何防止: 對于有可能被多個線程同時訪問的變量使用排他訪問控制,具體方法包括使用mutex(互斥量)或者使用atomic變量。

---------------------------------

作者注加一條規則:凡是若干線程(協程)對一個共享變量進行同步操作,且其中有一個是寫操作的,那么讀/寫都要考慮使用原子操作。

---------------------------------

race condition(競態條件)

讀取到數據中間狀態的的情形就是 race condition。相對于數據爭用(data race),競態條件(race condition)指的是更加高層次的更加復雜的現象,一般需要在設計并行程序時進行細致入微的分析,才能確定。(也就是隱藏得更深).

定義:受各線程上代碼執行的順序和時機的影響,程序的運行結果產生(預料之外)的變化。

后果:如果存在競態條件(race condition),多次運行程序對于同一個輸入將會有不同的結果,但結果并非完全不可預測,它將由輸入數據和各線程的執行順序共同決定。

如何預防:競態條件產生的原因很多是對于同一個資源的一系列連續操作并不是原子性的,也就是說有可能在執行的中途被其他線程搶占,同時這個“其他線程”剛好也要訪問這個資源。解決方法通常是:將這一系列操作作為一個critical section(臨界區)。

2、undefined behavior(未定義行為)

未定義行為是指執行某種計算機代碼所產生的結果,這種代碼在當前程序狀態下的行為在其所使用的語言標準中沒有規定。在 Go 的內存模型中,有race的Go程序的行為是未定義行為

3、go run/build -race(開啟race檢測)

golang在1.1之后引入了競爭檢測的概念。我們可以使用go run -race或者go build -race來進行競爭檢測。-race選項打開了data race detector用來檢查這個錯誤,而且關閉了相關的編譯器優化(作者注:就是為了不讓編譯器優化代碼,能看清楚完整代碼)。(原因是)go編譯器認為race代碼是dead code,可能直接優化掉。

4、原子性

一個或者多個操作在 CPU 執行的過程中不被中斷的特性,稱為原子性(atomicity)。這些操作對外表現成一個不可分割的整體,他們要么都執行,要么都不執行,外界不會看到他們只執行到一半的狀態。

5、原子操作

原子操作(atomic operation)指的是由多步操作組成的一個操作。如果該操作不能原子地執行,則要么執行完所有步驟,要么一步也不執行,不可能只執行所有步驟的一個子集。

在單核系統里,單個的機器指令可以看成是原子操作(如果有編譯器優化、亂序執行等情況除外),在單核CPU中, 能夠在一個指令中完成的操作都可以看作為原子操作, 因為中斷只發生在指令間;

在多核系統中,單個的機器指令就不是原子操作,因為多核系統里是多指令流并行運行的,一個核在執行一個指令時,其他核同時執行的指令有可能操作同一塊內存區域,從而出現數據競爭現象。

多核系統中的原子操作通常使用內存柵障(memory barrier)來實現,即一個CPU核在執行原子操作時,其他CPU核必須停止對內存操作或者不對指定的內存進行操作,這樣才能避免數據競爭問題。

在多核CPU的時代,體系中運行著多個獨立的CPU,即使是可以在單個指令中完成的操作也可能會被干擾. 典型的例子就是decl指令(遞減指令), 它細分為三個過程: “讀->改->寫”, 涉及兩次內存操作。如果多個CPU運行的多個進程在同時對同一塊內存執行這個指令,那情況是無法預測的。

二、代碼分析

race 多協程寫分析

golang在1.1之后引入了競爭檢測的概念。我們可以使用go run -race 或者 go build -race 來進行競爭檢測。

golang語言內部大概的實現就是同時開啟多個goroutine執行同一個命令,并且紀錄每個變量的狀態。

package main

import(
"time"
"fmt"
)

func main() {
a := 1
go func(){
a = 2
}()
a = 3
fmt.Println("a is ", a)

time.Sleep(2 * time.Second)
}

如果使用go run -race 1.go,將出現下列提示:

a is  3
==================
WARNING: DATA RACE
Write at 0x00c00012c058 by goroutine 7:
main.main.func1()
E:/hello/list/main/1.go:11 +0x44

Previous write at 0x00c00012c058 by main goroutine:
main.main()
E:/hello/list/main/1.go:13 +0x92

Goroutine 7 (running) created at:
main.main()
E:/hello/list/main/1.go:10 +0x84
==================
Found 1 data race(s)
exit status 66

這個命令輸出了WARNING:DATA RACE

總結

本篇主要介紹了一些術語,引用了一條規則:凡是多線程對共享變量涉及到寫操作,都要考慮使用原子操作。

其次,介紹了-race選項,可以對代碼涉及競態的問題做個檢查。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2024-02-05 13:37:16

Go語言方法

2020-10-05 22:05:10

Linux系統編程時序競態

2023-06-27 13:46:00

前端競態promise

2022-11-11 15:49:09

前端JavaScript開發

2022-11-11 10:22:54

前端Promise

2019-05-09 08:57:40

HTTPSWindows臺式機Linux主機

2023-12-29 09:28:25

Java編程

2025-01-16 09:43:10

2023-11-07 08:28:08

GPT模型環境

2022-03-24 20:42:19

Vue3API 設計Vue

2023-12-22 14:07:00

Go輕量級Goroutines

2024-06-07 07:56:35

2022-01-25 09:15:39

V8垃圾回收算法

2024-01-05 08:45:35

Go語言map

2020-08-20 07:41:52

Git原理版本

2023-09-28 08:51:58

Java數據

2020-03-17 19:39:50

區塊鏈區塊鏈技術

2021-11-26 10:12:10

量子AI計算機

2021-02-02 09:10:12

Go語言二進制

2025-01-08 09:07:06

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久久久久久动漫 | 婷婷色网 | 欧美精品一区二区三区在线 | 国产精品久久久久久影视 | 色综合久久久 | 亚洲一区二区三区免费观看 | 国产精品区二区三区日本 | 欧美精品中文字幕久久二区 | 久久区二区 | 最新中文字幕在线播放 | 日韩成人精品一区二区三区 | 一级黄色生活视频 | 99热热99| 免费观看一级毛片 | 九九久久99| 九九久久精品 | 中文字幕精品视频在线观看 | 国产精品毛片一区二区三区 | 日韩一区二区在线视频 | 久久婷婷国产麻豆91 | 欧美毛片免费观看 | 久久精品| 欧美黄色片 | 久久99精品久久久久久国产越南 | www.操.com| 成人欧美一区二区三区 | 九九精品网 | 欧美v在线观看 | 国产午夜精品久久久 | 精品久久久久久亚洲综合网 | 精品真实国产乱文在线 | 欧美日韩久久 | 亚洲 日本 欧美 中文幕 | 亚洲成人观看 | 中文字幕在线视频观看 | jizz视频| 欧美精品综合在线 | 99视频在线免费观看 | 97国产精品 | 久久精品成人 | 国产精品国产三级国产aⅴ浪潮 |