Ваш метод receive()
не использует блокировку, поэтому send()
удержание блокировки не влияет на receive()
.
И так как send()
и receive()
работают самостоятельноgoroutine, send()
доберется до точки, где он отправляет значение 5
на канал, и, таким образом, прием в receive()
может продолжаться, и он будет печатать его в следующей строке.
Также обратите внимание, что для использования каналов из нескольких программ вам не требуется «внешняя» синхронизация.Каналы безопасны для одновременного использования, гонки данных не могут быть спроектированы.Подробнее см. Если я правильно использую каналы, нужно ли мне использовать мьютексы?
Если метод receive()
также использует блокировку следующим образом:
func (s *S) receive() {
s.mu.Lock()
num := <-s.ch
s.mu.Unlock()
fmt.Printf("%d\n", num)
}
Тогда да, ничего не будет напечатано, потому что получение не может произойти, пока send()
не снимет блокировку, но это не может произойти, пока кто-то не получит от канала.
И в этом случае программа завершит работучерез 1 секунду, ничего не печатая, потому что, когда сон закончится, основная программа завершится, как и все ваше приложение.Он не ждет завершения других неосновных процедур.Подробнее см. Нет вывода из goroutine в Go .
Редактировать:
Да, вы неправильно поняли блокировку.Блокировка sync.Mutex
блокирует только само значение мьютекса, но не блокирует все значение структуры (не может).И «сам блокирует значение» означает, что если другая программа также вызывает свой метод Mutex.Lock()
, этот вызов будет блокироваться до тех пор, пока блокировка не будет снята путем вызова метода Mutex.Unlock()
.Когда он разблокирован, процедура, заблокированная при вызове Mutex.Lock()
, будет продолжать блокировать мьютекс и возвращаться.