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)
	}
}

posted @ 2024-12-09 20:53  __username  阅读(4)  评论(0编辑  收藏  举报

本文作者:DIVMonster

本文链接:https://www.cnblogs.com/guangzan/p/12886111.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。