banner
biuaxia

biuaxia

"万物皆有裂痕,那是光进来的地方。"
github
bilibili
tg_channel

チャンネル

title: チャネル
date: 2022-06-29 14:39:00
toc: false
index_img: http://api.btstu.cn/sjbz/?lx=m_dongman&cid=7
category:

  • Go
    tags:
  • 解決
  • 回数
  • ポインター

注意:共有メモリを通信して共有しないでください。

  • すべてのチャネルの送信操作はブロックされます(ブロックとも呼ばれます)。
  • waitGroup を使用する場合は、必ずポインターと組み合わせて使用してください。
  • 実際の問題を解決するには、順序が保証されているかどうか、または順不同の状況で検査する必要があります。

コードを直接示します。コメントに注意してください:

package main

import "fmt"

type worker struct {
	in   chan int
	done chan bool
}

func main() {
	const count = 4

	var workers [count]worker
	for i := 0; i < count; i++ {
		workers[i] = createWorker(i)
	}

	for i, worker := range workers {
		worker.in <- 'a' + i
	}

	for i, worker := range workers {
		worker.in <- 'A' + i
	}

	for _, worker := range workers {
		<-worker.done
		<-worker.done
	}
}

func doWork(id int, w worker) {
	for {
		fmt.Printf("No.%d worker received: %c\n", id, <-w.in)
		go func() { w.done <- true }() // バッファ付きチャネルを作成して問題を解決することもできます。ここでは done: make(chan bool, 1) と同じ効果で、ブロックされなくなり、結果が順不同になります。
		// w.done <- true
	}
}

func createWorker(id int) worker {
	w := worker{
		in:   make(chan int),  // inチャネルを追加すると、2回のデータ送信が完了し、2回のdoneの受信が開始され、結果が順不同になります。
		done: make(chan bool), // doneチャネルを追加すると、最初のデータ送信が完了すると、直ちに2回目のデータ送信が開始され、結果が順不同になります。
	}
	go doWork(id, w)
	return w
}

sync.WaitGroupを使用して実装する場合:

package main

import (
	"fmt"
	"sync"
)

type worker struct {
	in   chan int
	done *sync.WaitGroup
}

func main() {
	const count = 4

	var wg sync.WaitGroup

	var workers [count]worker
	for i := 0; i < count; i++ {
		workers[i] = createWorker(i, &wg)
	}

	wg.Add(count * 2)
	for i, worker := range workers {
		worker.in <- 'a' + i
	}

	for i, worker := range workers {
		worker.in <- 'A' + i
	}

	wg.Wait()
}

func doWork(id int, w worker) {
	for {
		fmt.Printf("No.%d worker received: %c\n", id, <-w.in)
		w.done.Done()
	}
}

func createWorker(id int, wg *sync.WaitGroup) worker {
	w := worker{
		in:   make(chan int),
		done: wg,
	}
	go doWork(id, w)
	return w
}

関数とWaitGroupを一緒に使用する:

package main

import (
	"fmt"
	"sync"
)

type worker struct {
	in   chan int
	done func()
}

func main() {
	const count = 4

	var wg sync.WaitGroup

	var workers [count]worker
	for i := 0; i < count; i++ {
		workers[i] = createWorker(i, &wg)
	}

	wg.Add(count * 2)
	for i, worker := range workers {
		worker.in <- 'a' + i
	}

	for i, worker := range workers {
		worker.in <- 'A' + i
	}

	wg.Wait()
}

func doWork(id int, w worker) {
	for {
		fmt.Printf("No.%d worker received: %c\n", id, <-w.in)
		w.done()
	}
}

func createWorker(id int, wg *sync.WaitGroup) worker {
	w := worker{
		in:   make(chan int),
		done: wg.Done,
	}
	go doWork(id, w)
	return w
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。