> 백엔드 개발 > Golang > Golang의 동기화 방법을 소개하는 기사

Golang의 동기화 방법을 소개하는 기사

PHPz
풀어 주다: 2023-04-14 10:40:22
원래의
1053명이 탐색했습니다.

Golang은 동시 프로그래밍을 지원하는 언어이지만 동시 프로그래밍에서는 데이터 불일치가 쉽게 발생할 수 있습니다. 따라서 Golang에서는 프로그램의 정확성과 신뢰성을 보장하기 위해 동기화 방법을 사용해야 합니다. 이번 글에서는 Golang의 동기화 방법을 소개하겠습니다.

1. 뮤텍스 잠금

뮤텍스 잠금은 가장 일반적으로 사용되는 동기화 메커니즘 중 하나입니다. 뮤텍스 잠금을 통해 공유 리소스를 잠글 수 있어 경쟁 조건이 발생하지 않고 동시에 하나의 스레드만 액세스할 수 있습니다. Golang에서 뮤텍스 잠금은 표준 라이브러리의 sync.Mutex를 통해 구현됩니다. 다음은 뮤텍스 잠금에 대한 샘플 코드입니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

package main

 

import (

    "fmt"

    "sync"

    "time"

)

 

func main() {

    var lock sync.Mutex

    var wg sync.WaitGroup

 

    var count int

 

    for i := 0; i < 10; i++ {

        wg.Add(1)

        go func() {

            lock.Lock() // 加锁

            defer lock.Unlock() // 解锁

 

            count++

            time.Sleep(time.Second)

            fmt.Println(count)

            wg.Done()

        }()

    }

 

    wg.Wait()

}

로그인 후 복사

2. 읽기-쓰기 잠금

읽기-쓰기 잠금은 여러 스레드가 동시에 공유 리소스를 읽을 수 있도록 허용하는 특수한 뮤텍스 잠금이지만 쓰기 시에는 , 동시에 하나의 스레드만 공유 리소스에 액세스할 수 있습니다. Golang에서는 표준 라이브러리의 sync.RWMutex를 통해 읽기-쓰기 잠금이 구현됩니다. 다음은 읽기-쓰기 잠금에 대한 샘플 코드입니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

package main

 

import (

    "fmt"

    "sync"

    "time"

)

 

func main() {

    var lock sync.RWMutex

    var wg sync.WaitGroup

 

    var count int

 

    for i := 0; i < 10; i++ {

        wg.Add(1)

        go func(idx int) {

            // 多个线程读操作可以同时进行

            lock.RLock()

            fmt.Printf("读协程%d,count=%d\n", idx, count)

            lock.RUnlock()

 

            // 一个线程写操作时,其它线程无法读写

            lock.Lock()

            count++

            fmt.Printf("写协程%d,count=%d\n", idx, count)

            time.Sleep(time.Second)

            lock.Unlock()

 

            wg.Done()

        }(i)

    }

 

    wg.Wait()

}

로그인 후 복사

3. 조건 변수

조건 변수는 스레드가 특정 조건에 따라 동기화할 수 있도록 하는 동기화 메커니즘입니다. Golang에서는 조건 변수가 표준 라이브러리의 sync.Cond를 통해 구현됩니다. 다음은 조건변수에 대한 샘플 코드입니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

package main

 

import (

    "fmt"

    "sync"

    "time"

)

 

func main() {

    var lock sync.Mutex

    var wg sync.WaitGroup

    var cond = sync.NewCond(&lock)

 

    done := false

 

    for i := 0; i < 5; i++ {

        wg.Add(1)

        go func(idx int) {

            lock.Lock()

            for !done {

                cond.Wait() // 等待通知

            }

            fmt.Printf("协程%d收到通知\n", idx)

            lock.Unlock()

 

            wg.Done()

        }(i)

    }

 

    time.Sleep(time.Second)

 

    lock.Lock()

    done = true // 向所有协程发送通知

    cond.Broadcast()

    lock.Unlock()

 

    wg.Wait()

}

로그인 후 복사

4. 원자 연산

원자 연산은 잠금 없이 메모리 데이터를 읽고 쓸 수 있는 연산입니다. Golang에서 원자 연산은 표준 라이브러리의 sync/atomic을 통해 구현됩니다. 다음은 원자 연산을 위한 샘플 코드입니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

package main

 

import (

    "fmt"

    "sync/atomic"

)

 

func main() {

    var value int32

    atomic.StoreInt32(&value, 10)

    fmt.Println(atomic.LoadInt32(&value))

 

    atomic.AddInt32(&value, 5)

    fmt.Println(atomic.LoadInt32(&value))

 

    atomic.CompareAndSwapInt32(&value, 15, 20) // 如果value等于15,则将其更新为20

    fmt.Println(atomic.LoadInt32(&value))

}

로그인 후 복사

뮤텍스 잠금, 읽기-쓰기 잠금, 조건 변수 및 원자 연산과 같은 동기화 방법을 통해 Golang 프로그램의 정확성과 신뢰성을 효과적으로 보장할 수 있습니다.

위 내용은 Golang의 동기화 방법을 소개하는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿