@rps1

Перед выполнением в цикле exec.Command желательно «разогреть»?

Понадобилось проверить в цикле доступность нескольких хостов.
Командой типа:
cmd := exec.Command("ping", host, "-n", "1")
с помощью горутин.
for _, address := range Addresses {
		go NetWorkStatus(address, ch)
	}

Заметил, что при повторном цикле время выполнения команды сократилось более чем на секунду. Причём во втором цикле "новые" адреса обрабатывались с такой же скоростью, как и "старые", к которым уже обращались ранее.
И также, если перед циклом вызвать просто
exec.Command("ping", "127.0.0.1", "-n", "1").Run()
картина такая же.

Набросал небольшой тест

package main
import (
	"fmt"
	"os/exec"
	"time"
)

const (
	C_NORMAL = "\033[0m"
	C_RED    = "\033[31;1m"
	C_GREEN  = "\033[32;1m"
)

func NetWorkStatus(host string, ch chan<- string) {
	cmd := exec.Command("ping", host, "-n", "1")
	start := time.Now()
	err := cmd.Run()
	secs := time.Since(start).Seconds()
	var color, result string
	if err != nil {
		result = "Error"
		color = C_RED
	} else {
		result = "OK   "
		color = C_GREEN
	}
	ch <- fmt.Sprintf("%s%-15s %s (%.2fs)%s", color, host, result, secs, C_NORMAL)
}

func test(Addresses []string) {
	ch := make(chan string)
	start := time.Now()
	for _, address := range Addresses {
		go NetWorkStatus(address, ch)
	}
	for range Addresses {
		fmt.Println(<-ch)
	}
	fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
}

func main() {
	//exec.Command("ping", "127.0.0.1", "-n", "1").Run()
	test([]string{"8.8.8.8", "1.1.1.1", "192.1.1.1", "192.1.1.2"})
	test([]string{"8.8.8.8", "87.250.250.242", "192.1.1.1", "192.0.0.2"})
}

62c403cc87a0c233956808.png
Собственно, вопрос - непонятно подобное поведение. Получается, все команды, выполняемые в цикле горутинами, длятся дольше на эту секунду с лишним.
В общем, я явно чего-то не понимаю. И, возможно, что-то не то делаю...

При выполнении команд в цикле без горутин (последовательным вызовом команд) картина следующая:
62c4007e996e6879929877.pngПервая команда медленнее, остальные одинаково быстрее. И, кстати, "успешный" пинг вдвое быстрее, чем в случае с горутинами...

P.S. Код для Windows, советовать использовать icmp (и библиотеки go-ping и go-fastping) не надо. Программа должна работать без прав админа. В том числе на Windows 7.
  • Вопрос задан
  • 71 просмотр
Решения вопроса 2
@mayton2019
Bigdata Engineer
Скорее всего ничего тут поделать нельзя. Под windows процессы стартуют медленнее чем под Linux.

Попробуй ради интереса замени PING на DIR и посмотри как изменится время.
Ответ написан
1. exec.Command - это системный вызов с сопутствующим поиском исполняемого файла, его загрузкой в память и исполнением. Для повторного запуска количество шагов уменьшается.
2. горутины исполняются столько времени, сколько им необходимо, если ничего не ограничивает их по времени. Если нужно, используй context.WithTimeout и exec.CommandContext.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы