Multithreading 简单队列模型示例
是否有一个简单的程序来演示Go中队列的工作方式。Multithreading 简单队列模型示例,multithreading,go,queue,Multithreading,Go,Queue,是否有一个简单的程序来演示Go中队列的工作方式。 我只需要在队列中添加数字1到10,然后使用另一个线程并行地从队列中提取这些数字。可以安全并发使用的队列基本上是一种语言结构: 一个通道——从设计上讲——是安全的,可用于并发和并发操作。这里详细说明了这一点:发送给它的值是按照发送顺序接收的 您可以在此处阅读有关频道的更多信息: 一个非常简单的例子: c := make(chan int, 10) // buffer for 10 elements // Producer: send elemen
我只需要在队列中添加数字1到10,然后使用另一个线程并行地从队列中提取这些数字。可以安全并发使用的队列基本上是一种语言结构: 一个通道——从设计上讲——是安全的,可用于并发和并发操作。这里详细说明了这一点:发送给它的值是按照发送顺序接收的 您可以在此处阅读有关频道的更多信息: 一个非常简单的例子:
c := make(chan int, 10) // buffer for 10 elements
// Producer: send elements in a new goroutine
go func() {
for i := 0; i < 10; i++ {
c <- i
}
close(c)
}()
// Consumer: receive all elements sent on it before it was closed:
for v := range c {
fmt.Println("Received:", v)
}
请注意,通道缓冲区(本例中为10)与要“通过”它发送的元素数无关。缓冲区告诉通道可以“存储”多少个元素,或者换句话说,当没有人从它接收时,可以在不阻塞的情况下发送多少个元素。当通道的缓冲区已满时,进一步的发送将被阻止,直到有人开始从中接收值。您可以使用通道(并发使用安全)和等待组从队列中并发读取
package main
import (
"fmt"
"sync"
)
func main() {
queue := make(chan int)
wg := new(sync.WaitGroup)
wg.Add(1)
defer wg.Wait()
go func(wg *sync.WaitGroup) {
for {
r, ok := <-queue
if !ok {
wg.Done()
return
}
fmt.Println(r)
}
}(wg)
for i := 1; i <= 10; i++ {
queue <- i
}
close(queue)
}
主程序包
进口(
“fmt”
“同步”
)
func main(){
队列:=make(chan int)
wg:=新建(sync.WaitGroup)
工作组.添加(1)
延迟工作组等待()
go func(wg*sync.WaitGroup){
为了{
r、 确定:=另一个选项是创建并实现一个队列接口
,带有用于并发的通道备份类型
下面是你如何使用它
queue := GetIntConcurrentQueue()
defer queue.Close()
// queue.Enqueue(1)
// myInt, errQueueClosed := queue.DequeueBlocking()
// myInt, errIfNoInt := queue.DequeueNonBlocking()
更详细的例子如下-
下面是完整的实现,下面是它的主要部分
//可以是任何支持类型,如果需要,甚至可以是“接口{}”。
//有关类型转换说明,请参见stackoverflow.com/q/11403050/3960399。
类型IntConcurrentQueue接口{
//将int插入队列
排队(整数)
//如果队列中没有任何内容或已调用Close(),则将返回错误
DequeueNonBlocking()(int,错误)
//将一直阻止,直到队列中有要返回的值为止。
//如果已调用Close(),则将出错。
DequeueBlocking()(int,错误)
//初始化后应使用DEBER调用Close
关闭()
}
func GetIntConcurrentQueue()IntConcurrentQueue{
return&intChannelQueue{c:make(chan int)}
}
类型intChannelQueue结构{
陈成英
}
func(q*intChannelQueue)排队(i int){
q、 c所以go中的队列是最常见的频道,这里有一个完整的教程:这种语言叫做“go”。“golang”是一个流行的互联网搜索引擎识别的标记,用于执行与这种语言相关的查询。
queue := GetIntConcurrentQueue()
defer queue.Close()
// queue.Enqueue(1)
// myInt, errQueueClosed := queue.DequeueBlocking()
// myInt, errIfNoInt := queue.DequeueNonBlocking()
// Can be any backing type, even 'interface{}' if desired.
// See stackoverflow.com/q/11403050/3960399 for type conversion instructions.
type IntConcurrentQueue interface {
// Inserts the int into the queue
Enqueue(int)
// Will return error if there is nothing in the queue or if Close() was already called
DequeueNonBlocking() (int, error)
// Will block until there is a value in the queue to return.
// Will error if Close() was already called.
DequeueBlocking() (int, error)
// Close should be called with defer after initializing
Close()
}
func GetIntConcurrentQueue() IntConcurrentQueue {
return &intChannelQueue{c: make(chan int)}
}
type intChannelQueue struct {
c chan int
}
func (q *intChannelQueue) Enqueue(i int) {
q.c <- i
}
func (q *intChannelQueue) DequeueNonBlocking() (int, error) {
select {
case i, ok := <-q.c:
if ok {
return i, nil
} else {
return 0, fmt.Errorf("queue was closed")
}
default:
return 0, fmt.Errorf("queue has no value")
}
}
func (q *intChannelQueue) DequeueBlocking() (int, error) {
i, ok := <-q.c
if ok {
return i, nil
}
return 0, fmt.Errorf("queue was closed")
}
func (q *intChannelQueue) Close() {
close(q.c)
}