Я бы не использовал глобальный sync.WaitGroup
, трудно понять, что происходит. Вместо этого просто определите его там, где вам нужно.
Вы звоните wg.Wait()
внутри блока цикла. Это в основном блокирует цикл каждую итерацию, ожидающую завершения goroutine. Что вы действительно хотите, так это порождать все горутины и только потом ждать их завершения.
if ok {
cmd := exec.Command("clear")
cmd.Stdout = os.Stdout
cmd.Run()
var wg sync.WaitGroup //I am about to spawn goroutines, I need to wait for them
for i.Cmp(bignum) < 0 {
wg.Add(1)
go func(i *big.Int) {
defer wg.Done()
go printKeys(i.String(), kpp)
i.Add(i, big.NewInt(1))
pages_queried += 1
infofunc(i)
}(i)
}
wg.Wait() //Now that all goroutines are working, let's wait
}
Нельзя избежать перекрытия печати, если у вас есть несколько процедур. Если это проблема, вы можете подумать об использовании Go * log stdlib, который добавит вам временные метки. Затем вы сможете сортировать их в хронологическом порядке.
В любом случае, разделение кода на большее количество подпрограмм не обеспечивает ускорения. Если проблема, которую вы пытаетесь решить, является по сути последовательной, то большее количество процедур просто добавит больше конкуренции и давления на планировщик Go, что приведет к противоположному результату. Подробнее здесь. Таким образом, процедура для infofunc
не поможет. Но это можно улучшить, используя библиотеку логгеров вместо простого пакета fmt
.
func infofunc(i *big.Int) {
duration := time.Since(start_time).Seconds()
if duration != 0 {
log.Printf("\033[5;0H")
log.Printf("Started at %s. Found: %d. Elapsed: %s. Queried: %d pages. Current page: %s. Rate: %d/s", start_time.String(), found, elapsed.String(), pages_queried, i.String(), (pages_queried / duration2))
}
}
Для printKeys
я бы не создавал так много goroutines, они не помогут, если работа, которую они должны выполнить, связана с CPU, что, похоже, имеет место здесь.
func printKeys(pageNumber string, keysPerPage int) {
keys := generateKeys(pageNumber, keysPerPage)
length := len(keys)
var addressesLen = len(addresses)
var wg sync.WaitGroup //Local WaitGroup
for i := 0; i < length; i++ {
wg.Add(1)
go func(i int) { //This goroutine could be removed, in my opinion.
defer wg.Done()
for ii := 0; ii < addressesLen; ii++ {
for _, v := range addresses {
if set[keys[i].compressed] || set[keys[i].uncompressed] {
log.Printf("Found an address: %v\n", v)
log.Printf("%v", keys[i])
log.Printf("\n")
foundAddresses += 1
found += 1
}
}
}
}(i)
foundAddresses = 0
}
wg.Wait()
}
Я бы предложил написать тест для этих функций, а затем включить трассировку. Таким образом, вы должны понять, где ваш код тратит большую часть времени.