@vGrabko99
html, css, js, php, golang, mysql

Почему возвращает значение третей рутины?

Я делаю простенький кластер (в научных целях)

У меня есть домен
example.com на нём код который по идее должен вернуть мне имя сервера который ответил быстрее всех. Но почему то всегда отвечал server3 первым. Не долго думая я привёл свой код где просто используеться fmt.print
package main

import "fmt"

func getDataFromServer(res chan string, serverName string) {
	fmt.Println(serverName)
	res <- serverName
}

func main() {
	res := make(chan string, 3)
	go getDataFromServer(res, "Server1")
	go getDataFromServer(res, "Server2")
	go getDataFromServer(res, "Server3")

	data := <- res
	fmt.Println(data)
}

По идее в этом коде 1 горутина должна завершаться первой и в терминал должно быть напечатано server1 но почему то постоянно печатает server3

А вот код которым я проверяю сервера
package main

import (
	"fmt"
	"log"
	"net/url"
)

func getDataFromServer(res chan string, serverName string) {
	ur := "http://" + serverName + "example.com"
	_, err := url.Parse(ur)
	if err != nil {
		log.Fatal(err)
	} else {
		res <- ur
	}
}

func main() {
	res := make(chan string, 3)
	go getDataFromServer(res, "Server1")
	go getDataFromServer(res, "Server2")
	go getDataFromServer(res, "Server3")
	go getDataFromServer(res, "Server4")
	go getDataFromServer(res, "Server5")

	data := <-res
	//по идее здесь должен быть url который ответил быстрее всех. Но почему то выводит адрес Server5 всегда
	fmt.Println(data)
}


Зарание спасибо
  • Вопрос задан
  • 308 просмотров
Решения вопроса 1
Go не гарантирует порядок выполнения горутин. Так что server1 не обязательно будет первым.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@mantyr
Пишу много Golang кода с удовольствием:)
Вот два примера для проверки что всё на самом деле работает верно (если мы правильно понимаем в чём вопрос).
package main

import "fmt"
import "time"

func getDataFromServer(res chan string, serverName string, delay int64) {
	fmt.Println(serverName)
	time.Sleep(time.Duration(delay)*time.Second)
	res <- "test_"+serverName
}

func main() {
  res := make(chan string, 3)
  go getDataFromServer(res, "Server1", 10)
  go getDataFromServer(res, "Server2", 11)
  go getDataFromServer(res, "Server3", 12)

  data := <- res
  fmt.Println(data)
}
Server3
Server1
Server2
test_Server1

package main

import "fmt"
import "time"

func getDataFromServer(res chan string, serverName string, delay int64) {
	fmt.Println(serverName)
	time.Sleep(time.Duration(delay)*time.Second)
	res <- "test_"+serverName
}

func main() {
  res := make(chan string, 3)
  go getDataFromServer(res, "Server1", 15)
  go getDataFromServer(res, "Server2", 11)
  go getDataFromServer(res, "Server3", 12)

  data := <- res
  fmt.Println(data)
}
Server3
Server1
Server2
test_Server2

Golang сам решает когда контекст переключать для большей производительности и меньших накладных расходов.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы