У меня проблема со стресс-тестом, которую я хочу решить с помощью простой синхронизации в Go. До сих пор я пытался найти документацию по моему конкретному варианту использования относительно синхронизации в Go, но не нашел ничего подходящего.
Чтобы быть более конкретным:
Я должен выполнить задачу, в которой мне нужно запустить большое количество потоков (в этом примере только с двумя потоками) в основной процедуре. Предполагается, что все инициированные работники должны самостоятельно подготовить некоторые действия по инициализации. Пока они не достигнут небольшой последовательности команд, которую я хочу, чтобы они выполнялись всеми программами одновременно, поэтому я хочу самосинхронизировать эти программы друг с другом. Для моей задачи очень важно, чтобы задержка выполнения основной подпрограммы, которая создает экземпляры всех других подпрограмм, не влияла на истинный параллелизм выполнения рабочих (на ярлыке #maximum параллельно в комментарии). Для этого я инициализирую группу ожидания с количеством запущенных подпрограмм в основной подпрограмме и передаю ее всем подпрограммам, чтобы они могли синхронизировать рабочий процесс друг друга.
Код выглядит примерно так:
import sync
func worker_action(wait_group *sync.WaitGroup) {
// ...
// initialization
// ...
defer wait_group.Done()
wait_group.Wait() // #label: wait
// sequence of maximum parallel instructions // #label: maximum parallel
// ...
}
func main() {
var numThreads int = 2 // the number of threads shall be much higher for the actual stress test
var wait_group sync.WaitGroup
wait_group.Add(numThreads)
for i := 0; i < numThreads; i++ {
go worker_action(&wait_group)
}
// ...
}
К сожалению, моя установка заходит в тупик, как только все goroutines достигли инструкции Wait (помеченной в комментарии #wait). Это верно для любого количества потоков, которые я запускаю с основной подпрограммы (даже два потока за короткое время оказываются в тупике).
С моей точки зрения, тупик не должен возникать из-за того, что непосредственно перед инструкцией ожидания каждая goroutine выполняет функцию done в той же группе ожидания.
Я неправильно понимаю, как работают группы ожидания? Например, нельзя ли выполнять функцию ожидания внутри программы, отличной от основной процедуры? Или может кто-нибудь подсказать мне, что еще мне не хватает?
Большое спасибо заранее.
EDIT:
Большое спасибо @tkausl. Это была действительно ненужная «отсрочка», которая вызвала проблему. Я не знаю, как я не мог видеть это сам.