# #go #concurrency #benchmarking #rpc #goroutine
Вопрос:
Я пытаюсь выполнить тест с go, используя rpc и команду exec., вот части моего кода. У меня есть мастер, чтобы отправить rpc работнику для выполнения какой-то работы.
func main() { var wg sync.WaitGroup var clients []*rpc.Client client, err := rpc.DialHTTP("tcp", "addr" ":1234") if err != nil { log.Fatal("dialing:", err) } reply := amp;Reply{} args := amp;Args{} clients = append(clients, client) fmt.Println(clients) err = clients[0].Call("Worker.Init", args, reply) if err != nil { log.Fatal("init error:", err) } // call for server to init channel // err = client.Call("Worker.Init", args, reply) args.A = 1 wg.Add(200) fmt.Println(time.Now().UnixNano()) for i := 0; i lt; 200; i { go func() { defer wg.Done() err = client.Call("Worker.DoJob", args, reply) if err != nil { log.Fatal("dojob error:", err) } fmt.Println("Done") }() } wg.Wait() fmt.Println(time.Now().UnixNano()) }
и рабочий кодекс
func (w *Worker) DoJob(args *Args, reply *Reply) error { // find a channel to do it w.c lt;- 1 runtime.LockOSThread() fmt.Println("exec") // cmd := exec.Command("docker", "run", "--rm", "ubuntu:16.04", "/bin/bash", "-c", "date %s%N") cmd := exec.Command("echo", "hello") err := cmd.Run() fmt.Println("exec done") if err != nil { reply.Err = err fmt.Println(err) } fmt.Println("done") lt;-w.c return nil }
Я использую чан размером 12, чтобы имитировать, что на машине всего 12 потоков, и после того, как я обнаружил, что он застрял в cmd.Run (), я изменил команду с запуска докера на простое эхо приветствия, но она все еще застряла между fmt.Println("exec")
и fmt.Println("exec done")
. Я не знаю, почему это происходит? Я отправляю слишком много rpc, поэтому многие rpc будут удалены?
Комментарии:
1. Я думаю, что проблема может быть в cmd.Run (), потому что после того, как я их прокомментирую, вся процедура, похоже, работает идеально
2. И я пытаюсь использовать
htop
, чтобы показать подробную информацию о системе, процедура go заняла целое ядро и застряла там, почему?