funcsum(s []int, c chanint) { sum := 0 for _, v := range s { sum += v } c <- sum // send sum to c } funcmain() { s := []int{7, 2, 8, -9, 4, 0} c := make(chanint) s1 := s[:len(s)/2] s2 := s[len(s)/2:] fmt.Println(s1) fmt.Println(s2) go sum(s1, c) go sum(s2, c) x, y := <-c, <-c // receive from c fmt.Println(x, y, x+y) }
输出结果为
1 2 3
[7 2 8] [-9 4 0] -5 17 12
3.2 Buffered Channels
make的第二个参数指定缓存的大小:ch := make(chan int, 100)。
通过缓存的使用,可以尽量避免阻塞,提供应用的性能。
有缓存的 channel 的声明方式为指定 make 函数的第二个参数,该参数为 channel 缓存的容量
funcmain() { gofunc() { time.Sleep(1 * time.Hour) }() c := make(chanint) gofunc() { for i := 0; i < 10; i = i + 1 { c <- i } close(c) }() for i := range c { fmt.Println(i) } fmt.Println("Finished") }
range c产生的迭代值为Channel中发送的值,它会一直迭代直到channel被关闭。上面的例子中如果把close(c)注释掉,程序会一直阻塞在for …… range那一行。
funcmain() { var c1, c2, c3 chanint var i1, i2 int select { case i1 = <-c1: fmt.Printf("received ", i1, " from c1\n") case c2 <- i2: fmt.Printf("sent ", i2, " to c2\n") case i3, ok := (<-c3): // same as: i3, ok := <-c3 if ok { fmt.Printf("received ", i3, " from c3\n") } else { fmt.Printf("c3 is closed\n") } default: fmt.Printf("no communication\n") } }
receiver #2 get 0 receiver #2 get 3 receiver #2 get 4 receiver #2 get 5 receiver #2 get 6 receiver #2 get 7 receiver #2 get 8 receiver #2 get 9 receiver #2 get 10 receiver #2 get 11 receiver #2 get 12 receiver #2 get 13 receiver #2 get 14 receiver #2 get 15 receiver #2 get 16 receiver #2 get 17 receiver #2 get 18 receiver #2 get 19 receiver #2 get 20 receiver #2 get 21 receiver #2 get 22 receiver #2 get 23 receiver #2 get 24 receiver #2 get 25 receiver #2 get 26 receiver #2 get 27 receiver #2 get 28 receiver #2 get 29 receiver #2 get 30 receiver #2 get 31 receiver #0 get 1 receiver #0 get 33 receiver #0 get 34 receiver #1 get 2 receiver #1 get 36 receiver #1 get 37 receiver #1 get 38 receiver #1 get 39 receiver #1 get 40 receiver #1 get 41 receiver #1 get 42 receiver #1 get 43 receiver #0 get 35 receiver #0 get 45 receiver #0 get 46 receiver #0 get 47 receiver #0 get 48 receiver #0 get 49 receiver #0 get 50 receiver #0 get 51 receiver #0 get 52 receiver #0 get 53 receiver #0 get 54 receiver #0 get 55 receiver #0 get 56 receiver #0 get 57 receiver #0 get 58 receiver #0 get 59 receiver #0 get 60 receiver #0 get 61 receiver #0 get 62 receiver #0 get 63 receiver #0 get 64 receiver #0 get 65 receiver #0 get 66 receiver #0 get 67 receiver #0 get 68 receiver #0 get 69 receiver #0 get 70 receiver #0 get 71 receiver #0 get 72 receiver #0 get 73 receiver #0 get 74 receiver #0 get 75 receiver #0 get 76 receiver #0 get 77 receiver #0 get 78 receiver #0 get 79 receiver #0 get 80 receiver #0 get 81 receiver #0 get 82 receiver #0 get 83 receiver #0 get 84 receiver #0 get 85 receiver #0 get 86 receiver #0 get 87 receiver #0 get 88 receiver #0 get 89 receiver #0 get 90 receiver #0 get 91 receiver #0 get 92 receiver #0 get 93 receiver #0 get 94 receiver #0 get 95 receiver #0 get 96 receiver #0 get 97 receiver #0 get 98 receiver #0 get 99 receiver #0 exit receiver #2 get 32 receiver #2 exit receiver #1 get 44 receiver #1 exit
receiver get 2000 receiver get 2001 receiver get 2002 receiver get 2003 receiver get 2004 receiver get 2005 receiver get 2006 receiver get 2007 receiver get 2008 receiver get 2009 receiver get 2010 receiver get 2011 receiver get 2012 receiver get 2013 receiver get 2014 receiver get 2015 receiver get 2016 receiver get 2017 receiver get 2018 receiver get 2019 receiver get 2020 receiver get 2021 receiver get 2022 receiver get 2023 receiver get 2024 receiver get 2025 receiver get 2026 receiver get 2027 receiver get 2028 receiver get 2029 receiver get 2030 receiver get 2031 receiver get 2032 receiver get 2033 receiver get 2034 receiver get 2035 receiver get 2036 receiver get 2037 receiver get 2038 receiver get 2039 receiver get 2040 receiver get 2041 receiver get 2042 receiver get 2043 receiver get 2044 receiver get 2045 receiver get 2046 receiver get 2047 receiver get 2048 receiver get 2049 receiver get 2050 receiver get 2051 receiver get 2052 receiver get 2053 receiver get 2054 receiver get 2055 receiver get 2056 receiver get 2057 receiver get 2058 receiver get 2059 receiver get 2060 receiver get 2061 receiver get 2062 receiver get 2063 receiver get 2064 receiver get 2065 receiver get 2066 receiver get 2067 receiver get 2068 receiver get 2069 receiver get 2070 receiver get 2071 receiver get 2072 receiver get 2073 receiver get 2074 receiver get 2075 receiver get 2076 receiver get 2077 receiver get 2078 receiver get 2079 receiver get 2080 receiver get 2081 receiver get 2082 receiver get 2083 receiver get 2084 receiver get 2085 receiver get 2086 receiver get 2087 receiver get 2088 receiver get 2089 receiver get 2090 receiver get 2091 receiver get 2092 receiver get 2093 receiver get 2094 receiver get 2095 receiver get 2096 receiver get 2097 receiver get 2098 receiver get 2099 receiver get 2100 receiver get 2101 receiver get 0 receiver get 1000 receiver get 2102 receiver get 2103 receiver get 2104 receiver get 2105 receiver get 2106 receiver get 2107 receiver get 2108 receiver get 2109 receiver get 2110 receiver get 2111 receiver get 2112 receiver get 2113 receiver get 2114 receiver get 2115 receiver get 2116 receiver get 2117 receiver get 2118 receiver get 2119 receiver get 2120 receiver get 2121 receiver get 2122 receiver get 2123 receiver get 2124 receiver get 2125 receiver get 2126 receiver get 1 receiver get 1001 receiver get 2127 receiver get 2 receiver get 3 receiver get 4 receiver get 5 receiver get 6 receiver get 7 receiver get 8 receiver get 1002 receiver get 2128 receiver get 9 receiver get 1003 receiver get 2129 receiver get 10 receiver get 1004 receiver get 2130 receiver get 11 receiver get 1005 receiver get 2131 receiver get 12 receiver get 13 receiver get 14 receiver get 15 receiver get 16 receiver get 17 receiver get 1006 receiver get 2132 receiver get 18 receiver get 1007 receiver get 2133 receiver get 19 receiver get 20 receiver get 21 receiver get 22 receiver get 23 receiver get 24 receiver get 25 receiver get 26 receiver get 27 receiver get 28 receiver get 29 receiver get 30 receiver get 31 receiver get 32 receiver get 33 receiver get 34 receiver get 35 receiver get 36 receiver get 37 receiver get 38 receiver get 39 receiver get 40 receiver get 41 receiver get 42 receiver get 43 receiver get 44 receiver get 45 receiver get 46 receiver get 47 receiver get 48 receiver get 49 receiver get 50 receiver get 51 receiver get 52 receiver get 53 receiver get 54 receiver get 55 receiver get 56 receiver get 57 receiver get 1008 receiver get 2134 receiver get 58 receiver get 1009 receiver get 2135 receiver get 2136 receiver get 2137 receiver get 2138 receiver get 2139 receiver get 2140 receiver get 2141 receiver get 2142 receiver get 2143 receiver get 2144 receiver get 59 receiver get 1010 receiver get 2145 receiver get 60 receiver get 61 receiver get 62 receiver get 63 receiver get 64 receiver get 65 receiver get 66 receiver get 67 receiver get 68 receiver get 69 receiver get 70 receiver get 71 receiver get 72 receiver get 73 receiver get 74 receiver get 75 receiver get 76 receiver get 77 receiver get 78 receiver get 79 receiver get 80 receiver get 81 receiver get 82 receiver get 83 receiver get 84 receiver get 1011 receiver get 2146 receiver get 85 receiver get 86 receiver get 1012 receiver get 2147 receiver get 87 receiver get 1013 receiver get 1014 receiver get 1015 receiver get 1016 receiver get 1017 receiver get 1018 receiver get 1019 receiver get 1020 receiver get 1021 receiver get 1022 receiver get 1023 receiver get 1024 receiver get 1025 receiver get 1026 receiver get 1027 receiver get 1028 receiver get 1029 receiver get 1030 receiver get 1031 receiver get 2148 receiver get 2149 receiver get 88 receiver get 1032 receiver get 2150 receiver get 2151 receiver get 89 receiver get 1033 receiver get 2152 receiver get 90 receiver get 1034 receiver get 1035 receiver get 1036 receiver get 1037 receiver get 1038 receiver get 1039 receiver get 1040 receiver get 1041 receiver get 1042 receiver get 1043 receiver get 1044 receiver get 1045 receiver get 1046 receiver get 1047 receiver get 1048 receiver get 1049 receiver get 1050 receiver get 2153 receiver get 91 receiver get 1051 receiver get 2154 receiver get 92 receiver get 93 receiver get 94 receiver get 95 receiver get 96 receiver get 97 receiver get 98 receiver get 99 receiver get 100 receiver get 101 receiver get 102 receiver get 103 receiver get 104 receiver get 105 receiver get 106 receiver get 107 receiver get 1052 receiver get 2155 receiver get 108 receiver get 109 receiver get 110 receiver get 111 receiver get 112 receiver get 113 receiver get 114 receiver get 115 receiver get 116 receiver get 117 receiver get 118 receiver get 119 receiver get 120 receiver get 121 receiver get 122 receiver get 123 receiver get 124 receiver get 125 receiver get 126 receiver get 127 receiver get 128 receiver get 129 receiver get 130 receiver get 131 receiver get 132 receiver get 133 receiver get 134 receiver get 135 receiver get 136 receiver get 137 receiver get 138 receiver get 139 receiver get 140 receiver get 1053 receiver get 2156 receiver get 141 receiver get 1054 receiver get 1055 receiver get 1056 receiver get 1057 receiver get 2157 receiver get 142 receiver get 1058 receiver get 143 receiver get 2158 receiver get 1059 receiver get 144 receiver get 2159 receiver get 1060 receiver get 145 receiver get 2160 receiver get 1061 receiver get 146 receiver get 2161 receiver get 1062 receiver get 147 receiver get 2162 receiver get 1063 receiver get 148 receiver get 2163 receiver get 1064 receiver get 149 receiver get 2164 receiver get 1065 receiver get 150 receiver get 2165 receiver get 1066 receiver get 151 receiver get 152 receiver get 153 receiver get 154 receiver get 155 receiver get 156 receiver get 157 receiver get 158 receiver get 159 receiver get 160 receiver get 161 receiver get 162 receiver get 163 receiver get 164 receiver get 165 receiver get 166 receiver get 167 receiver get 168 receiver get 169 receiver get 170 receiver get 171 receiver get 172 receiver get 173 receiver get 174 receiver get 175 receiver get 176 receiver get 177 receiver get 178 receiver get 179 receiver get 180 receiver get 181 receiver get 182 receiver get 183 receiver get 184 receiver get 1067 receiver get 2166 receiver get 185 receiver get 1068 receiver get 2167 receiver get 186 receiver get 1069 receiver get 2168 receiver get 2169 receiver get 2170 receiver get 1070 receiver get 187 receiver get 2171 receiver get 1071 receiver get 188 receiver get 2172 receiver get 189 receiver get 2173 receiver get 190 receiver get 1072 receiver get 2174 receiver get 191 receiver get 1073 receiver get 2175 receiver get 2176 receiver get 192 receiver get 193 receiver get 1074 receiver get 2177 receiver get 194 receiver get 1075 receiver get 1076 receiver get 195 receiver get 2178 receiver get 1077 receiver get 196 receiver get 2179 receiver get 1078 receiver get 197 receiver get 2180 receiver get 1079 receiver get 198 receiver get 2181 receiver get 1080 receiver get 199 receiver get 2182 receiver get 1081 receiver get 200 receiver get 2183 receiver get 1082 receiver get 201 receiver get 2184 receiver get 1083 receiver get 202 receiver get 2185 receiver get 1084 receiver get 203 receiver get 2186 receiver get 1085 receiver get 1086 receiver get 2187 receiver get 204 receiver get 1087 receiver get 2188 receiver get 205 receiver get 1088 receiver get 2189 receiver get 2190 receiver get 2191 receiver get 206 receiver get 1089 receiver get 2192 receiver get 207 receiver get 1090 receiver get 2193 receiver get 208 receiver get 209 receiver get 1091 receiver get 2194 receiver get 210 receiver get 1092 receiver get 2195 receiver get 2196 receiver get 2197 receiver get 2198 receiver get 2199 receiver get 2200 receiver get 2201 receiver get 2202 receiver get 2203 receiver get 2204 receiver get 2205 receiver get 2206 receiver get 2207 receiver get 2208 receiver get 2209 receiver get 2210 receiver get 2211 receiver get 2212 receiver get 2213 receiver get 2214 receiver get 2215 receiver get 2216 receiver get 2217 receiver get 2218 receiver get 2219 receiver get 2220 receiver get 2221 receiver get 2222 receiver get 2223 receiver get 2224 receiver get 2225 receiver get 2226 receiver get 2227 receiver get 211 receiver get 1093 receiver get 2228 receiver get 2229 receiver get 2230 receiver get 212 receiver get 1094 receiver get 2231 receiver get 213 receiver get 1095 receiver get 1096 receiver get 1097 receiver get 1098 receiver get 1099 receiver get 1100 receiver get 1101 receiver get 1102 receiver get 1103 receiver get 1104 receiver get 1105 receiver get 1106 receiver get 1107 receiver get 1108 receiver get 1109 receiver get 1110 receiver get 1111 receiver get 1112 receiver get 1113 receiver get 1114 receiver get 1115 receiver get 1116 receiver get 1117 receiver get 1118 receiver get 1119 receiver get 1120 receiver get 2232 receiver get 214 receiver get 1121 receiver get 2233 receiver get 2234 receiver get 2235 receiver get 2236 receiver get 2237 receiver get 2238 receiver get 2239 receiver get 2240 receiver get 2241 receiver get 2242 receiver get 2243 receiver get 2244 receiver get 2245 receiver get 2246 receiver get 2247 receiver get 2248 receiver get 2249 receiver get 2250 receiver get 2251 receiver get 2252 receiver get 2253 receiver get 1122 receiver get 215 receiver get 2254 receiver get 1123 receiver get 216 receiver get 2255 receiver get 2256 receiver get 1124 receiver get 217 receiver get 2257 receiver get 1125 receiver get 218 receiver get 2258 receiver get 2259 receiver get 2260 receiver get 2261 receiver get 2262 receiver get 2263 receiver get 2264 receiver get 2265 receiver get 2266 receiver get 2267 receiver get 2268 receiver get 2269 receiver get 2270 receiver get 2271 receiver get 2272 receiver get 2273 receiver get 2274 receiver get 2275 receiver get 2276 receiver get 2277 receiver get 2278 receiver get 2279 receiver get 2280 receiver get 1126 receiver get 219 receiver get 2281 receiver get 2282 receiver get 1127 receiver get 2283 receiver get 1128 receiver get 2284 receiver get 1129 receiver get 2285 receiver get 220 receiver get 221 receiver get 222 receiver get 223 receiver get 224 receiver get 225 receiver get 226 receiver get 227 receiver get 228 receiver get 229 receiver get 230 receiver get 231 receiver get 232 receiver get 233 receiver get 234 receiver get 235 receiver get 236 receiver get 237 receiver get 238 receiver get 239 receiver get 240 receiver get 241 receiver get 242 receiver get 243 receiver get 244 receiver get 245 receiver get 246 receiver get 247 receiver get 248 receiver get 1130 receiver get 2286 receiver get 249 receiver get 1131 receiver get 2287 receiver get 2288 receiver get 2289 receiver get 2290 receiver get 2291 receiver get 2292 receiver get 2293 receiver get 2294 receiver get 2295 receiver get 2296 receiver get 2297 receiver get 2298 receiver get 2299 receiver get 2300 receiver get 2301 receiver get 2302 receiver get 2303 receiver get 2304 receiver get 2305 receiver get 2306 receiver get 2307 receiver get 2308 receiver get 2309 receiver get 2310 receiver get 2311 receiver get 2312 receiver get 2313 receiver get 2314 receiver get 2315 receiver get 2316 receiver get 2317 receiver get 2318 receiver get 2319 receiver get 2320 receiver get 1132 receiver get 250 receiver get 2321 receiver get 2322 receiver get 2323 receiver get 2324 receiver get 2325 receiver get 2326 receiver get 2327 receiver get 2328 receiver get 2329 receiver get 2330 receiver get 2331 receiver get 2332 receiver get 2333 receiver get 2334 receiver get 2335 receiver get 2336 receiver get 2337 receiver get 2338 receiver get 2339 receiver get 2340 receiver get 2341 receiver get 2342 receiver get 2343 receiver get 2344 receiver get 2345 receiver get 2346 receiver get 2347 receiver get 2348 receiver get 1133 receiver get 251 receiver get 2349 receiver get 1134 receiver get 252 receiver get 253 receiver get 254 receiver get 255 receiver get 256 receiver get 257 receiver get 258 receiver get 259 receiver get 260 receiver get 261 receiver get 262 receiver get 263 receiver get 264 receiver get 265 receiver get 266 receiver get 267 receiver get 268 receiver get 269 receiver get 2350 receiver get 2351 receiver get 2352 receiver get 2353 receiver get 2354 receiver get 2355 receiver get 2356 receiver get 270 receiver get 1135 receiver get 271 receiver get 2357 receiver get 1136 receiver get 272 receiver get 2358 receiver get 2359 receiver get 1137 receiver get 273 receiver get 2360 receiver get 1138 receiver get 274 receiver get 275 receiver get 276 receiver get 277 receiver get 278 receiver get 279 receiver get 280 receiver get 281 receiver get 282 receiver get 283 receiver get 284 receiver get 285 receiver get 286 receiver get 287 receiver get 288 receiver get 289 receiver get 290 receiver get 291 receiver get 292 receiver get 293 receiver get 294 receiver get 295 receiver get 296 receiver get 297 receiver get 298 receiver get 299 receiver get 300 receiver get 301 receiver get 302 receiver get 303 receiver get 304 receiver get 2361 receiver get 1139 receiver get 305 receiver get 2362 receiver get 1140 receiver get 306 receiver get 2363 receiver get 2364 receiver get 2365 receiver get 2366 receiver get 2367 receiver get 2368 receiver get 2369 receiver get 2370 receiver get 2371 receiver get 2372 receiver get 2373 receiver get 2374 receiver get 2375 receiver get 2376 receiver get 2377 receiver get 2378 receiver get 2379 receiver get 2380 receiver get 2381 receiver get 2382 receiver get 2383 receiver get 2384 receiver get 2385 receiver get 1141 receiver get 307 receiver get 2386 receiver get 1142 receiver get 2387 receiver get 308 receiver get 1143 receiver get 2388 receiver get 309 receiver get 1144 receiver get 2389 receiver get 310 receiver get 1145 receiver get 2390 receiver get 2391 receiver get 2392 receiver get 2393 receiver get 2394 receiver get 2395 receiver get 2396 receiver get 2397 receiver get 311 receiver get 1146 receiver get 2398 receiver get 312 receiver get 1147 receiver get 2399 receiver get 313 receiver get 1148 receiver get 2400 receiver get 314 receiver get 1149 receiver get 2401 receiver get 315 receiver get 1150 receiver get 2402 receiver get 316 receiver get 1151 receiver get 2403 receiver get 1152 receiver get 2404 receiver get 317 receiver get 1153 receiver get 1154 receiver get 1155 receiver get 1156 receiver get 1157 receiver get 1158 receiver get 1159 receiver get 1160 receiver get 2405 receiver get 318 receiver get 1161 receiver get 1162 receiver get 1163 receiver get 1164 receiver get 1165 receiver get 1166 receiver get 1167 receiver get 1168 receiver get 1169 receiver get 1170 receiver get 1171 receiver get 1172 receiver get 1173 receiver get 1174 receiver get 1175 receiver get 1176 receiver get 1177 receiver get 1178 receiver get 1179 receiver get 1180 receiver get 1181 receiver get 1182 receiver get 1183 receiver get 1184 receiver get 2406 receiver get 319 receiver get 1185 receiver get 2407 receiver get 320 receiver get 1186 receiver get 321 receiver get 2408 receiver get 2409 receiver get 1187 receiver get 322 receiver get 2410 receiver get 1188 receiver get 323 receiver get 2411 receiver get 1189 receiver get 324 receiver get 2412 receiver get 1190 receiver get 325 receiver get 2413 receiver get 1191 receiver get 326 receiver get 2414 receiver get 1192 receiver get 327 receiver get 2415 receiver get 1193 receiver get 328 receiver get 2416 receiver get 1194 receiver get 329 receiver get 2417 receiver get 2418 receiver get 2419 receiver get 1195 receiver get 330 receiver get 2420 receiver get 1196 receiver get 331 receiver get 2421 receiver get 1197 receiver get 332 receiver get 2422 receiver get 1198 receiver get 333 receiver get 2423 receiver get 1199 receiver get 334 receiver get 2424 receiver get 1200 receiver get 335 receiver get 2425 receiver get 1201 receiver get 336 receiver get 2426 receiver get 1202 receiver get 337 receiver get 2427 receiver get 1203 receiver get 338 receiver get 2428 receiver get 1204 receiver get 339 receiver get 2429 receiver get 1205 receiver get 340 receiver get 341 receiver get 342 receiver get 343 receiver get 344 receiver get 345 receiver get 346 receiver get 347 receiver get 348 receiver get 349 receiver get 350 receiver get 351 receiver get 352 receiver get 353 receiver get 354 receiver get 355 receiver get 356 receiver get 357 receiver get 358 receiver get 359 receiver get 360 receiver get 361 receiver get 362 receiver get 363 sender #0 exit sender #1 exit sender #2 exit
// start N worker goroutines for i := 0; i < N; i++ { gofunc(n int) { for { select { // wait for exit signal case <-exit: fmt.Printf("worker goroutine #%d exit\n", n) done <- struct{}{} return case <-time.After(time.Second): fmt.Printf("worker goroutine #%d is working...\n", n) } } }(i) }
time.Sleep(3 * time.Second) // broadcast exit signal close(exit) // wait for all worker goroutines exit for i := 0; i < N; i++ { <-done } fmt.Println("main goroutine exit") }
6.3 信号量
channel 的读/写相当于信号量的 P / V 操作,下面的示例程序中 channel 相当于信号量:
func(bar Bar)ServeConsumer(customerId int) { log.Print("-> consumer#", customerId, " enters the bar") seat := <-bar // need a seat to drink log.Print("consumer#", customerId, " drinks at seat#", seat) time.Sleep(time.Second * time.Duration(2+rand.Intn(6))) log.Print("<- consumer#", customerId, " frees seat#", seat) bar <- seat // free the seat and leave the bar }
funcmain() { rand.Seed(time.Now().UnixNano())
bar24x7 := make(Bar, 10) // the bar has 10 seats // Place seats in an bar. for seatId := 0; seatId < cap(bar24x7); seatId++ { bar24x7 <- Seat(seatId) // none of the sends will block }
// a new consumer try to enter the bar for each second for customerId := 0; ; customerId++ { time.Sleep(time.Second) go bar24x7.ServeConsumer(customerId) } }