Multithreading 如何在不等待另一个goroutine设置的情况下读取频道?
我在goroutine中使用频道时遇到问题Multithreading 如何在不等待另一个goroutine设置的情况下读取频道?,multithreading,go,goroutine,Multithreading,Go,Goroutine,我在goroutine中使用频道时遇到问题 var test = make(chan string) func main() { go initChan() for i := 0; i < 2; i++ { go readChan() } var input string fmt.Scanln(&input) } func initChan() { for i := 0; i < 100; i++ {
var test = make(chan string)
func main() {
go initChan()
for i := 0; i < 2; i++ {
go readChan()
}
var input string
fmt.Scanln(&input)
}
func initChan() {
for i := 0; i < 100; i++ {
test <- "Iteration num: " + strconv.Itoa(i)
time.Sleep(time.Second * 5)
}
}
func readChan() {
for {
message := <- test
log.Println(message)
}
}
我需要在不等待测试变量更新的情况下读取线程。
现在每个readChan()都在等待initChan()更新测试变量
是否可以使readChan()线程一次工作而不必为每个线程等待initChan()
var test = make(chan string)
var mapChan = make(map[int]chan string)
var count = 3
func main() {
go initChan()
go deamon()
for i := 0; i < count; i++ {
mapChan[i] = make(chan string)
go readChan(i)
}
var input string
fmt.Scanln(&input)
}
func deamon() {
for {
message := <-test
for i := 0; i < count; i++ {
mapChan[i] <- message
}
}
}
func initChan() {
for i := 0; i < 100; i++ {
test <- "Iteration num: " + strconv.Itoa(i)
time.Sleep(time.Second * 1)
}
}
func readChan(i int) {
for {
select {
case message := <-mapChan[i]:
log.Println(message)
default:
// Do for not when written on channel
}
}
}
var测试=make(chan字符串)
var mapChan=make(映射[int]chan字符串)
变量计数=3
func main(){
开始
去迪蒙
对于i:=0;i 消息:=如果我正确理解了您的问题,此解决方案可能会有所帮助。我使用了一个大小为1的缓冲通道,以便作为发送方的goroutine在非缓冲通道的情况下永远不会被阻止。您可以阅读有关通道的更多信息:
主程序包
进口(
“日志”
“strconv”
“同步”
“时间”
)
//大小为1的缓冲通道保证数据的延迟传输
//一旦goroutine发送到频道,接收者goroutine就会将其删除
//然后,接收方goroutine执行该工作,但发送方goroutine未被阻止
//因为在接收者收到它后,大小再次为0,但可能尚未处理它
var测试=制造(chan字符串,1)
func main(){
var wg sync.WaitGroup
工作组.添加(2)
//在主goroutine返回之前,等待其他goroutine完成
延迟工作组等待()
go initChan(&wg)
go readChan(&wg)
}
func initChan(wg*sync.WaitGroup){
推迟工作组完成()
对于i:=0;i<100;i++{
//连续发送
test@Stairdeck如果我引用您的问题,那么我的解决方案非常适合。通道被读取并处理(例如打印到标准输出)而负责发送到通道的另一个goroutine没有被阻止。不,我需要同时从所有线程输出,甚至测试变量也没有更新。在我的示例中,像3行迭代num:0,每个线程一行这样的输出。你可以构建这个检查输出。我已经编辑了答案,我认为这解决了你的问题。@StairdeckI需要所有线程同时输出,即使测试变量也不会更新。输出如3行迭代num:0,在我的示例中,每个线程一行。我已根据您的要求更新了我的答案。对于测试通道上的每个发送,所有侦听线程都将接收。希望这能解决您的问题。
var test = make(chan string)
var mapChan = make(map[int]chan string)
var count = 3
func main() {
go initChan()
go deamon()
for i := 0; i < count; i++ {
mapChan[i] = make(chan string)
go readChan(i)
}
var input string
fmt.Scanln(&input)
}
func deamon() {
for {
message := <-test
for i := 0; i < count; i++ {
mapChan[i] <- message
}
}
}
func initChan() {
for i := 0; i < 100; i++ {
test <- "Iteration num: " + strconv.Itoa(i)
time.Sleep(time.Second * 1)
}
}
func readChan(i int) {
for {
select {
case message := <-mapChan[i]:
log.Println(message)
default:
// Do for not when written on channel
}
}
}
package main
import (
"log"
"strconv"
"sync"
"time"
)
// Buffered channel with size 1 guarantees delayed delivery of data
// As soon as the goroutine sends to the channel, the reciever goroutine dequeus it
// Then the reciver goroutines does the work, but the sender goroutine isn't blocked
// As the size is again 0 after the reciever recieved it but might haven't processed it yet
var test = make(chan string, 1)
func main() {
var wg sync.WaitGroup
wg.Add(2)
// Waits for other goroutines to complete before the main goroutine returns
defer wg.Wait()
go initChan(&wg)
go readChan(&wg)
}
func initChan(wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 100; i++ {
// Sends continuously
test <- "Iteration num: " + strconv.Itoa(i)
time.Sleep(time.Second * 5)
}
close(test)
}
func readChan(wg *sync.WaitGroup) {
defer wg.Done()
var message string
var ok bool
// Reciever deques the value as soon as it recieves it
// But might take time to proceed
for {
select {
case message, ok = <-test:
// If channel is closed
if ok == false {
return
}
log.Println(message)
default:
log.Println(message)
}
}
}