Как работать с конкурентным доступом к одной ячейке памяти?

В языке Go конкурентный доступ к одной ячейке памяти можно реализовать с помощью мьютексов или атомарных операций.

Мьютексы в Go представлены типом sync.Mutex. Мьютекс позволяет заблокировать доступ к определенному участку кода только для одной горутины одновременно, что гарантирует корректность работы с общей ячейкой памяти. Для использования мьютекса, необходимо вызвать его метод Lock() перед доступом к общей ячейке памяти и метод Unlock() после завершения работы с ячейкой. Это обеспечит синхронизацию доступа к ячейке для всех горутин:

package main

import (
	"fmt"
	"sync"
)

var sharedData int
var mutex sync.Mutex

func main() {
	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()

		mutex.Lock()
		sharedData = 42
		mutex.Unlock()
	}()

	go func() {
		defer wg.Done()

		mutex.Lock()
		fmt.Println(sharedData)
		mutex.Unlock()
	}()

	wg.Wait()
}

Атомарные операции в Go используются для выполнения чтения и записи к ячейке памяти одновременно без блокировки. Go предоставляет набор атомарных операций в пакете sync/atomic, таких как AddInt32, LoadInt64, StorePointer, и т. д. При использовании атомарных операций, несколько горутин могут одновременно изменять или считывать значение общей ячейки памяти без необходимости блокировки:

package main

import (
	"fmt"
	"sync/atomic"
)

var sharedData int32

func main() {
	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()

		atomic.StoreInt32(&sharedData, 42)
	}()

	go func() {
		defer wg.Done()

		fmt.Println(atomic.LoadInt32(&sharedData))
	}()

	wg.Wait()
}

Обратите внимание, что при работе с конкурентным доступом к одной ячейке памяти, необходимо быть внимательными и проверять наличие гонок данных (data races). Гонка данных возникает, когда несколько горутин обращаются к общей ячейке памяти без синхронизации и приводит к неопределенным результатам. Поэтому использование мьютексов или атомарных операций необходимо в случае, когда одна ячейка памяти изменяется и считывается из разных горутин.