Проблема с взаимным исполнением рутины одновременного GO

StackOverflow https://stackoverflow.com/questions/8373329

Вопрос

В моем коде есть три параллельные процедуры. Я стараюсь дать краткий обзор моего кода,

Routine 1 {
do something

*Send int to Routine 2
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 2 {
do something

*Send int to Routine 1
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 3 {
do something

*Send int to Routine 1
Send int to Routine 2
Print Something
Print Something*

do something
}

main {
routine1
routine2
routine3
}

Я хочу, чтобы, в то время как коды между двумя делают что -то (коды между двумя звездными оценками) выполняются, поток управления не должен перейти к другим процедурам GO. Например, когда Prontine1 выполняет события между двумя звездами (отправка и печать событий), подпрограмма 2 и 3 должны быть заблокированы (означает, что поток выполнения не проходит в подпрограмму 2 или 3 из подпрограммы 1). После завершения последнего печать Поток исполнения может передать рутину 2 или 3. Может кто -нибудь помочь мне, указав, как я могу достичь этого? Можно ли реализовать вышеупомянутую спецификацию WaitGroup? Может ли кто -нибудь показать мне, приведя простой пример, как реализовать указанный пример, используя waitgroup. Спасибо.

NB: Может быть, это повторный вопрос это. Анкет Я пытался, используя этот механизм синхронизации, однако, может быть потому, что у меня есть большой код, поэтому я не мог правильно положить блокировку, и он создает ситуацию в тупике (или может быть моей метод является Ошибка производства) Может ли кто -нибудь помочь мне с помощью простой процедуры, поэтому я могу достичь этого. Я привожу простой пример своего кода здесь Где здесь я хочу поместить две отпечатки и отправить событие в Mutex (для подпрограммы 1), таким образом, подпрограмма 2 не может прервать его. Можете ли вы помочь мне, как это возможно. Одно возможное решение, данное,http://play.golang.org/p/-uoqsqbjks что дает ошибку.

Это было полезно?

Решение

почему ты хочешь сделать это?

Проблема тупика заключается в том, что если вы не разрешаете запланировать другие Goroutines, то ваш канал отправляет не может продолжаться, если не будет буферизации. Каналы Go имеют конечную буферизацию, так что вы получите состояние гонки при истощении, прежде чем их отправили, пока они полны. Вы можете представить бесконечную буферизацию или поставить каждую отправку в свою собственную goroutine, но это снова сводится к: почему вы пытаетесь это сделать; Чего вы пытаетесь достичь?

Другое дело: если вы хотите только убедиться в взаимном исключении трех наборов кода между *S, то да, вы можете использовать Mutexes. Если вы хотите убедиться, что нет Код прерывает ваш блок, независимо от того, где он был приостановлен, тогда вам может потребоваться использовать время выполнения. Это довольно низкий уровень, и вам нужно знать, что вы делаете, и они редко нужны. Из вас не нужно, чтобы не было никаких других работ, вам придется иметь время выполнения. Gomaxprocs (1), что в настоящее время является дефолтом.

Другие советы

Проблема в ответе на ваш вопрос заключается в том, что, кажется, никто не понимает, в чем на самом деле такая проблема. Я вижу, что вы неоднократно спрашиваете примерно о том же, хотя прогресс не был достигнут. Там нет обид в этом. Это попытка помочь вам по предложению переформулировать вашу проблему таким образом, понятно для других. В качестве возможного хорошего побочного эффекта некоторые проблемы решают себя, когда они объясняют другим понятным образом. Я испытывал это много раз сам.

Еще один намек может быть в подозрительном сочетании явной синхронизации и связи канала. Это не значит, что дизайн обязательно нарушен. Это просто не происходит в типичном/простом случае. Еще раз, ваша проблема может быть нетипичной/не тривиальной.

Возможно, как -то возможно перепроектировать вашу проблему, используя только каналы. На самом деле я считаю, что каждая проблема, связанная с явной синхронизацией (в ходе), может быть закодирована при использовании только каналов. Тем не менее, это правда, что некоторые проблемы написаны с явной синхронизацией очень легко. Также каналовая связь, как бы дешевая, не так дешево, как большинство примитивов синхронизации. Но это можно учесть позже, когда код работает. Если «шаблон» для некоторых скажет, что в коде появится «Sync.mutex, можно будет переключиться на него, и гораздо проще сделать это, когда код уже работает, и мы надеемся, что есть тесты, чтобы наблюдать за вашим шагом, внося корректировки Анкет

Попробуйте подумать о своих goroutines, таких как независимые действующие агенты, которые:

  • Исключительно владеют данными, полученными с канала. Язык не будет применять это, вы должны развернуть дисциплину.
  • Больше не касайтесь данных, которые они отправили на канал. Это следует из первого правила, но достаточно важно, чтобы быть явным.
  • Взаимодействуйте с другими агентами (goroutines) типами данных, которые инкапсулируют целую единицу рабочего процесса/вычисления. Это устраняет, например, ваша более ранняя борьба с получением правильного количества сообщений канала до завершения «единицы».
  • Для каждого канала, который они используют, это должно быть абсолютно ясно в Если канал должен быть небеффер, должен быть буферирован для фиксированного количества элементов или если он может быть несвязанным.
  • Не нужно думать (знать) о том, что другие агенты делают выше, получая от них сообщение, если это необходимо для агента, чтобы выполнить свою собственную задачу - часть более широкой картины.

Использование даже таких немногих правил, надеемся, будет надеяться, что код, о котором легко рассуждать, и который обычно не требует никакой другой синхронизации. (Я намеренно игнорирую проблемы с эффективностью критических приложений миссии.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top