Jadual Kandungan
Apa Berlaku Sebelum" >Apa Berlaku Sebelum
Jika operasi baca r dan tulis w untuk pembolehubah v memenuhi dua syarat berikut, r adalah dibenarkan untuk memerhati w: " >Dalam satu goroutine, susunan berlaku-sebelum ialah susunan pelaksanaan program. Jadi apakah urutan yang berlaku-sebelum ini? Jom tengok syarat di bawah. Jika operasi baca r dan tulis w untuk pembolehubah v memenuhi dua syarat berikut, r adalah dibenarkan untuk memerhati w:
Pada ketika ini anda harus faham mengapa set syarat kedua lebih ketat daripada set syarat pertama. Di bawah set syarat pertama, w dibenarkan untuk diperhatikan, dan dalam set kedua, w dijamin untuk diperhatikan. " >Pada ketika ini anda harus faham mengapa set syarat kedua lebih ketat daripada set syarat pertama. Di bawah set syarat pertama, w dibenarkan untuk diperhatikan, dan dalam set kedua, w dijamin untuk diperhatikan.
Go的初始化" >Go的初始化
goroutine的创建结束" >goroutine的创建结束
Channel的发送和接收" >Channel的发送和接收
Lock" >Lock
Once" >Once
不正确的同步" >不正确的同步
Rumah pembangunan bahagian belakang Golang Model memori Vernakular Go Happen-Sebelum

Model memori Vernakular Go Happen-Sebelum

Jul 24, 2023 pm 03:47 PM
go model ingatan

Apabila berbilang gorout mengakses data yang sama secara serentak, operasi akses serentak mesti bersiri. Siri baca dan tulis dalam Go boleh dijamin melalui komunikasi saluran atau primitif penyegerakan lain (seperti kunci mutex, kunci baca-tulis dalam pakej penyegerakan dan operasi atom dalam penyegerakan/atom).

Berlaku Sebelum

Dalam satu goroutine, tingkah laku membaca dan menulis mestilah konsisten dengan perintah pelaksanaan yang ditetapkan oleh program. Dalam erti kata lain, penyusun dan pemproses boleh menyusun semula arahan dalam satu goroutine tanpa mengubah tingkah laku yang ditakrifkan oleh spesifikasi bahasa.

a := 1
b := 2
Salin selepas log masuk

Disebabkan penyusunan semula arahan, b := 2 boleh mendahului a := 1Dilaksanakan. Dalam goroutine tunggal, pelarasan perintah pelaksanaan tidak akan menjejaskan keputusan akhir. Tetapi masalah mungkin timbul dalam pelbagai senario goroutine. b := 2可能先于a := 1执行。单goroutine中,该执行顺序的调整并不会影响最终结果。但多个goroutine场景下可能就会出现问题。

var a, b int
// goroutine A
go func() {
    a := 5
    b := 1
}()
// goroutine B
go func() {
    for b == 1 {}
    fmt.Println(a)
}()
Salin selepas log masuk

执行上述代码时,预期goroutine B能够正常输出5,但因为指令重排序,b := 1可能先于a := 5

func sleep() bool {
   time.Sleep(time.Second)
   return true
}

go fmt.Println(sleep())
Salin selepas log masuk
Salin selepas log masuk

Apabila melaksanakan kod di atas, goroutine B dijangka akan mengeluarkan 5 seperti biasa, tetapi disebabkan oleh penyusunan semula arahan, b := 1 boleh mendahului a := 5 dilaksanakan dan goroutine B akhirnya boleh mengeluarkan 0. 🎜
"

Nota: Contoh di atas adalah contoh yang salah dan hanya untuk ilustrasi.

"

Untuk menjelaskan keperluan untuk operasi baca dan tulis, Go memperkenalkan happens before, yang mewakili kaedah untuk melaksanakan operasi ingatan. .

Apa Berlaku Sebelum

Jika peristiwa e1 berlaku sebelum peristiwa e2, maka kita katakan e2 berlaku selepas e1. Begitu juga, jika e1 tidak berlaku sebelum e2 atau selepas e2, maka kita katakan bahawa e1 dan e2 berlaku serentak.

Dalam satu goroutine, susunan berlaku-sebelum ialah susunan pelaksanaan program. Jadi apakah urutan yang berlaku-sebelum ini? Jom tengok syarat di bawah. Jika operasi baca r dan tulis w untuk pembolehubah v memenuhi dua syarat berikut, r adalah dibenarkan untuk memerhati w:

r tidak berlaku sebelum w.

Tiada operasi tulis lain berlaku selepas w dan sebelum r.

  1. Untuk memastikan operasi baca r bagi pembolehubah v boleh memerhatikan operasi tulis tertentu w, adalah perlu untuk memastikan bahawa w adalah satu-satunya operasi tulis yang dibenarkan untuk diperhatikan oleh r. Kemudian, jika r dan w kedua-duanya memenuhi syarat berikut, r boleh
    memastikan
  2. memerhati w:
  3. w berlaku sebelum r.

Operasi tulis lain berlaku sebelum w dan selepas r.

  1. Tiada konkurensi dalam satu goroutine, kedua-dua syarat ini adalah setara. Lao Xu berkembang berdasarkan ini dan mendapati bahawa kedua-dua set syarat ini adalah sama setara untuk persekitaran operasi teras tunggal. Dalam kes konkurensi, set syarat terakhir adalah lebih ketat daripada set pertama.

    Jika anda keliru, anda betul! Lao Xu juga keliru pada mulanya kedua-dua set syarat ini adalah sama. Atas sebab ini, Lao Xu membandingkannya secara khas berulang kali dengan teks asal untuk memastikan bahawa pemahaman di atas adalah betul.

    Model memori Vernakular Go Happen-Sebelum

    Mari ubah pemikiran kita dan lakukan penaakulan songsang. Jika dua set syarat adalah sama, maka tidak perlu menulis teks asal dua kali Sudah tentu, perkara itu tidak mudah.

    Model memori Vernakular Go Happen-Sebelum

    Sebelum meneruskan analisis, saya ingin mengucapkan terima kasih kepada guru Cina saya, tanpa anda, saya tidak akan dapat menemui perbezaan mereka.

    r tidak berlaku Sebelum w, situasi yang mungkin bagi r ialah r berlaku selepas w atau pada masa yang sama dengan w, seperti yang ditunjukkan dalam rajah di bawah (pepejal menunjukkan bahawa ia boleh berlaku pada masa yang sama). r没有发生在w之前,则r可能的情况是r发生在w之后或者和w同时发生,如下图(实心表示可同时)。

    Model memori Vernakular Go Happen-Sebelum

    没有其他写操作发生在w之后和r之前

    Model memori Vernakular Go Happen-Sebelum
    Model memori Vernakular Go Happen-SebelumTiada operasi tulis lain berlaku selepas w dan sebelum r, kemudian Penulisan lain w' mungkin berlaku sebelum w atau pada masa yang sama dengan w, atau ia mungkin berlaku selepas r atau pada masa yang sama dengan r, seperti yang ditunjukkan dalam rajah di bawah (pepejal menunjukkan bahawa ia boleh berlaku pada masa yang sama).

    Model memori Vernakular Go Happen-SebelumSet syarat kedua adalah sangat jelas w berlaku sebelum r dan operasi tulis lain hanya boleh berlaku sebelum w atau selepas r, seperti yang ditunjukkan dalam rajah di bawah (ruang kosong menunjukkan bahawa ia tidak boleh pada masa yang sama. ).

    Pada ketika ini anda harus faham mengapa set syarat kedua lebih ketat daripada set syarat pertama. Di bawah set syarat pertama, w dibenarkan untuk diperhatikan, dan dalam set kedua, w dijamin untuk diperhatikan.

    Penyegerakan dalam Go

    🎜🎜Berikut adalah beberapa acara penyegerakan yang dipersetujui dalam Go Mereka boleh memastikan bahawa program mengikut prinsip berlaku-sebelum, supaya goroutin serentak agak teratur. 🎜

    Go的初始化

    程序初始化运行在单个goroutine中,但是该goroutine可以创建其他并发运行的goroutine。

    如果包p导入了包q,则q包init函数执行结束先于p包init函数的执行。main函数的执行发生在所有init函数执行完成之后。

    goroutine的创建结束

    goroutine的创建先于goroutine的执行。老许觉得这基本就是废话,但事情总是没有那么简单,其隐含之意大概是goroutine的创建是阻塞的。

    func sleep() bool {
       time.Sleep(time.Second)
       return true
    }
    
    go fmt.Println(sleep())
    Salin selepas log masuk
    Salin selepas log masuk

    上述代码会阻塞主goroutine一秒,然后才创建子goroutine。

    goroutine的退出是无法预测的。如果用一个goroutine观察另一个goroutine,请使用锁或者Channel来保证相对有序。

    Channel的发送和接收

    Channel通信是goroutine之间同步的主要方式。

    • Channel的发送动作先于相应的接受动作完成之前。

    • 无缓冲Channel的接受先于该Channel上的发送完成之前。

    这两点总结起来分别是开始发送开始接受发送完成接受完成四个动作,其时序关系如下。

    开始发送 > 接受完成
    开始接受 > 发送完成
    Salin selepas log masuk

    注意:开始发送和开始接受并无明确的先后关系

    • Channel的关闭发生在由于通道关闭而返回零值接受之前。

    • 容量为C的Channel第k个接受先于该Channel上的第k+C个发送完成之前。

    这里使用极限法应该更加易于理解,如果C为0,k为1则其含义和无缓冲Channel的一致。

    Lock

    对于任何sync.Mutex或sync.RWMutex变量l以及n < m,第n次l.Unlock()的调用先于第m次l.Lock()的调用返回。

    假设n为1,m为2,则第二次调用l.Lock()返回前一定要先调用l.UnLock()。

    对于sync.RWMutex的变量l存在这样一个n,使得l.RLock()的调用返回在第n次l.Unlock()之后发生,而与之匹配的l.RUnlock()发生在第n + 1次l.Lock()之前。

    不得不说,上面这句话简直不是人能理解的。老许将其翻译成人话:

    有写锁时:l.RLock()的调用返回发生在l.Unlock()之后。

    有读锁时:l.RUnlock()的调用发生在l.Lock()之前。

    注意:调用l.RUnlock()前不调用l.RLock()和调用l.Unlock()前不调用l.Lock()会引起panic。

    Once

    once.Do(f)中f的返回先于任意其他once.Do的返回。

    不正确的同步

    错误示范一

    var a, b int
    
    func f() {
     a = 1
     b = 2
    }
    
    func g() {
     print(b)
     print(a)
    }
    
    func main() {
     go f()
     g()
    }
    Salin selepas log masuk

    这个例子看起来挺简单,但是老许相信大部分人应该会忽略指令重排序引起的异常输出。假如goroutine f指令重排序后,b=2先于a=1发生,此时主goroutine观察到b发生变化而未观察到a变化,因此有可能输出20

    老许在本地实验了多次结果都是输出0020这个输出估计只活在理论之中了。

    错误示范二

    var a string
    var done bool
    
    func setup() {
     a = "hello, world"
     done = true
    }
    
    func doprint() {
     if !done {
      once.Do(setup)
     }
     print(a)
    }
    
    func twoprint() {
     go doprint()
     go doprint()
    }
    Salin selepas log masuk

    这种双重检测本意是为了避免同步的开销,但是依旧有可能打印出空字符串而不是“hello, world”。说实话老许自己都不敢保证以前没有写过这样的代码。现在唯一能想到的场景就是其中一个goroutine doprint执行到done = true(指令重排序导致done=true先于a="hello, world"执行)时,另一个goroutine doprint刚开始执行并观察到done的值为true从而打印空字符串。

Atas ialah kandungan terperinci Model memori Vernakular Go Happen-Sebelum. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Pemahaman mendalam tentang kitaran hayat fungsi Golang dan skop pembolehubah Pemahaman mendalam tentang kitaran hayat fungsi Golang dan skop pembolehubah Apr 19, 2024 am 11:42 AM

Dalam Go, kitaran hayat fungsi termasuk definisi, pemuatan, pemautan, pemulaan, panggilan dan skop pembolehubah dibahagikan kepada tahap fungsi dan tahap blok Pembolehubah dalam fungsi boleh dilihat secara dalaman, manakala pembolehubah dalam blok hanya kelihatan dalam blok .

Bagaimana untuk memadankan cap masa menggunakan ungkapan biasa dalam Go? Bagaimana untuk memadankan cap masa menggunakan ungkapan biasa dalam Go? Jun 02, 2024 am 09:00 AM

Dalam Go, anda boleh menggunakan ungkapan biasa untuk memadankan cap masa: susun rentetan ungkapan biasa, seperti yang digunakan untuk memadankan cap masa ISO8601: ^\d{4}-\d{2}-\d{2}T \d{ 2}:\d{2}:\d{2}(\.\d+)?(Z|[+-][0-9]{2}:[0-9]{2})$ . Gunakan fungsi regexp.MatchString untuk menyemak sama ada rentetan sepadan dengan ungkapan biasa.

Bagaimana untuk menghantar mesej Go WebSocket? Bagaimana untuk menghantar mesej Go WebSocket? Jun 03, 2024 pm 04:53 PM

Dalam Go, mesej WebSocket boleh dihantar menggunakan pakej gorila/soket web. Langkah khusus: Wujudkan sambungan WebSocket. Hantar mesej teks: Panggil WriteMessage(websocket.TextMessage,[]bait("Mesej")). Hantar mesej binari: panggil WriteMessage(websocket.BinaryMessage,[]bait{1,2,3}).

Perbezaan antara bahasa Golang dan Go Perbezaan antara bahasa Golang dan Go May 31, 2024 pm 08:10 PM

Bahasa Go dan Go adalah entiti yang berbeza dengan ciri yang berbeza. Go (juga dikenali sebagai Golang) terkenal dengan kesesuaiannya, kelajuan penyusunan pantas, pengurusan memori dan kelebihan merentas platform. Kelemahan bahasa Go termasuk ekosistem yang kurang kaya berbanding bahasa lain, sintaks yang lebih ketat dan kekurangan penaipan dinamik.

Bagaimana untuk mengelakkan kebocoran memori dalam pengoptimuman prestasi teknikal Golang? Bagaimana untuk mengelakkan kebocoran memori dalam pengoptimuman prestasi teknikal Golang? Jun 04, 2024 pm 12:27 PM

Kebocoran memori boleh menyebabkan memori program Go terus meningkat dengan: menutup sumber yang tidak lagi digunakan, seperti fail, sambungan rangkaian dan sambungan pangkalan data. Gunakan rujukan yang lemah untuk mengelakkan kebocoran memori dan objek sasaran untuk pengumpulan sampah apabila ia tidak lagi dirujuk dengan kuat. Menggunakan go coroutine, memori tindanan coroutine akan dikeluarkan secara automatik apabila keluar untuk mengelakkan kebocoran memori.

Bagaimana untuk menggunakan pembungkus ralat Golang? Bagaimana untuk menggunakan pembungkus ralat Golang? Jun 03, 2024 pm 04:08 PM

Dalam Golang, pembalut ralat membolehkan anda membuat ralat baharu dengan menambahkan maklumat kontekstual kepada ralat asal. Ini boleh digunakan untuk menyatukan jenis ralat yang dilemparkan oleh perpustakaan atau komponen yang berbeza, memudahkan penyahpepijatan dan pengendalian ralat. Langkah-langkahnya adalah seperti berikut: Gunakan fungsi ralat. Balut untuk membalut ralat asal kepada ralat baharu. Ralat baharu mengandungi maklumat kontekstual daripada ralat asal. Gunakan fmt.Printf untuk mengeluarkan ralat yang dibalut, memberikan lebih konteks dan kebolehtindakan. Apabila mengendalikan pelbagai jenis ralat, gunakan fungsi ralat. Balut untuk menyatukan jenis ralat.

Panduan untuk menguji unit fungsi serentak Go Panduan untuk menguji unit fungsi serentak Go May 03, 2024 am 10:54 AM

Unit menguji fungsi serentak adalah penting kerana ini membantu memastikan kelakuan mereka yang betul dalam persekitaran serentak. Prinsip asas seperti pengecualian bersama, penyegerakan dan pengasingan mesti dipertimbangkan semasa menguji fungsi serentak. Fungsi serentak boleh diuji unit dengan mensimulasikan, menguji keadaan perlumbaan dan mengesahkan keputusan.

Bagaimana untuk mencipta Goroutine yang diutamakan dalam Go? Bagaimana untuk mencipta Goroutine yang diutamakan dalam Go? Jun 04, 2024 pm 12:41 PM

Terdapat dua langkah untuk mencipta Goroutine keutamaan dalam bahasa Go: mendaftarkan fungsi penciptaan Goroutine tersuai (langkah 1) dan menentukan nilai keutamaan (langkah 2). Dengan cara ini, anda boleh mencipta Goroutine dengan keutamaan yang berbeza, mengoptimumkan peruntukan sumber dan meningkatkan kecekapan pelaksanaan.

See all articles