go 协程与channel(管道)
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"regexp"
"strings"
"sync"
)
func gomoun(c chan int) {
for i := 0; i < 10000; i++ {
c <- i
}
close(c) // 关闭管道
}
func main() {
ch1 := make(chan int)
go gomoun(ch1)
for v := range ch1 {
fmt.Println(v)
}
}
其它demo
package main
import (
"fmt"
"sync"
)
func worker(id int, ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
result := id * 2
ch <- result
}
func main() {
var wg sync.WaitGroup
ch := make(chan int, 5) // 缓冲 channel
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i, ch, &wg)
}
wg.Wait()
close(ch)
for res := range ch {
fmt.Println("Result:", res)
}
}
请求
package main
import (
"fmt"
"io/ioutil"
"net/http"
"sync"
)
// fetch 从指定的 URL 获取内容,并将结果存储到传递的 channel 中
func fetch(url string, wg *sync.WaitGroup, ch chan<- string) {
defer wg.Done() // 在 goroutine 完成时通知 WaitGroup
resp, err := http.Get(url)
if err != nil {
ch <- fmt.Sprintf("Failed to fetch from %s: %v", url, err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
ch <- fmt.Sprintf("Failed to read body from %s: %v", url, err)
return
}
ch <- fmt.Sprintf("Success from %s: %s", url, body)
}
func main() {
urls := []string{
"http://example.com",
"http://example.org",
"http://example.net",
}
var wg sync.WaitGroup
ch := make(chan string, len(urls)) // 创建一个足够大的 channel 存储所有结果
// 对每个 URL 启动一个 goroutine
for _, url := range urls {
wg.Add(1)
go fetch(url, &wg, ch)
}
wg.Wait() // 等待所有 goroutine 完成
close(ch) // 关闭 channel
// 打印所有从 channel 收集到的结果
for result := range ch {
fmt.Println(result)
}
}
package main
import (
"fmt"
"net/http"
"sync"
)
// sendRequest 发送HTTP GET请求到指定的URL并通过channel发送状态码
func sendRequest(url string, wg *sync.WaitGroup, ch chan<- int) {
defer wg.Done() // 在goroutine完成时调用Done
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error fetching URL", url, ":", err)
ch <- 0
return
}
ch <- resp.StatusCode
resp.Body.Close()
}
func main() {
urls := []string{
"https://example.com",
"https://api.github.com",
"https://google.com",
} // URL列表
var wg sync.WaitGroup
statusCh := make(chan int, len(urls)) // 创建一个channel,缓冲区大小为URL数量
for _, url := range urls {
wg.Add(1) // 增加等待组计数
go sendRequest(url, &wg, statusCh) // 启动goroutine来发送请求
}
wg.Wait() // 等待所有goroutine完成
close(statusCh) // 关闭channel
// 输出所有收到的状态码
for status := range statusCh {
fmt.Println("Received status code:", status)
}
}
next4
package main
import (
"fmt"
"io/ioutil"
"net/http"
"sync"
)
func fetchBaidu(id int, results chan<- string, wg *sync.WaitGroup) {
defer wg.Done() // 确保在完成后通知 WaitGroup
// 创建 HTTP 客户端
client := &http.Client{}
// 创建 GET 请求
req, err := http.NewRequest("GET", "https://www.baidu.com", nil)
if err != nil {
results <- fmt.Sprintf("协程 %d: 创建请求失败: %v", id, err)
return
}
// 添加头部信息
req.Header.Set("User-Agent", "Go-http-client/1.1")
// 发送请求
resp, err := client.Do(req)
if err != nil {
results <- fmt.Sprintf("协程 %d: 请求失败: %v", id, err)
return
}
defer resp.Body.Close()
// 读取响应
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
results <- fmt.Sprintf("协程 %d: 读取响应失败: %v", id, err)
return
}
results <- fmt.Sprintf("协程 %d: 响应状态码: %d, 内容长度: %d", id, resp.StatusCode, len(body))
}
func main() {
const numGoroutines = 10
var wg sync.WaitGroup
results := make(chan string, numGoroutines) // 缓冲通道,存储每个协程的结果
// 启动 10 个协程
for i := 1; i <= numGoroutines; i++ {
wg.Add(1)
go fetchBaidu(i, results, &wg)
}
// 等待所有协程完成
wg.Wait()
close(results) // 关闭通道,防止死锁
// 输出所有结果
for result := range results {
fmt.Println(result)
}
}
本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18596025