package main import ( "fmt" "io" "log" "math/rand" "net" "sync" "time" ) var mu sync.Mutex type queue struct { size int load []int } func remove(s []int, i int) []int { copy(s[i:], s[i+1:]) return s[:len(s)-1] } func work(q *queue) <-chan string { ch := make(chan string) go func() { for { mu.Lock() curLoad := len(q.load) mu.Unlock() if curLoad > 0 { mu.Lock() curValue := q.load[0] mu.Unlock() time.Sleep(time.Millisecond * time.Duration(curValue)) mu.Lock() q.load = remove(q.load, 0) mu.Unlock() ch <- "finished" } } }() return ch } func load(q *queue) { go func() { for { time.Sleep(time.Millisecond * time.Duration(rand.Intn(1000))) mu.Lock() q.load = append(q.load, rand.Intn(1000)) mu.Unlock() } }() } func printer(q *queue) { go func() { for { mu.Lock() fmt.Println(q) mu.Unlock() time.Sleep(time.Millisecond * 1000) } }() } func init() { rand.Seed(time.Now().UnixNano()) } var q = queue{ size: 10, } func main() { listener, err := net.Listen("tcp", "localhost:8080") if err != nil { log.Fatal(err) } go func() { for { conn, err := listener.Accept() if err != nil { log.Print(err) continue } handleConn(conn) } }() fmt.Println("here") load(&q) printer(&q) ch := work(&q) for { select { case <-ch: fmt.Println("finished something") } } } func handleConn(c net.Conn) { defer c.Close() for { mu.Lock() _, err := io.WriteString(c, fmt.Sprintf("%v\n", q)) mu.Unlock() if err != nil { return } time.Sleep(time.Millisecond * 100) } }