先说生产者消费者问题,就是多个生产者生产商品,放到一块缓存中,然后多个消费者从缓存取出并消费商品;
这里就有了三个对象或说实体,就是生产者,消费者,固定大小的缓存;<br />
然后就要说下一些限制条件,<br />
1. 如果缓存满了,生产者就不能生产商品了,只能等着有空间了再生产;<br />
2. 如果缓存空了,消费者就不能消费商品了,只能等以后商品了再消费; <br />
之前用c实现的时候,稍微麻烦一下;<br />
消费者:<br />
mutex.lock() <br />
while(container.size == 0){ <br />
pthread_cond_wait(nullcond, mutex) // 具体方法忘了... 就是如果缓存为空,利用条件变量,阻塞在这里,并把锁释放出来,好让生产者往里写啊...这里用while...是因为多个消费者都饿着的情况下,要一个一个来啊... <br />
} <br />
if(container.size == MAXSIZE) { <br />
container->pop// 消费一个商品 <br />
phtread_cond_sign(nullcond)// 同样具体方法不详,给条件变量发个信号,让它把因为缓存满的情况下的阻塞的条件放开,然后锁该等继续等... <br />
}else{ <br />
container->pop// 消费一个商品 <br />
} <br />
mutex.unlock() <br />
生产者:<br />
跟上面差不多,满的话,加个条件变量等着,放开锁,非满的信号来了,往里写...不能往里写,还得判断是不是空,空的话,给条件变量发个信号,可以先放一放了,然后往里写,unlock锁,结束
这个虽然有点绕,但是把共享资源的使用逻辑表现的很好... <br />
如果用golang来写, 就没有那么绕了... <br />
先把代码贴上...有空再写剩下的部分.<br />
-----------------------------------------------------------------------------------------------------
接着写...
先来介绍一个一个工具,就是平时练习或者写demo的工具tour,在终端输入go tool tour就可以启动tour服务(图就算了).
然后上代码
```
var stop = make(chan int)
var queue = make(chan interface{})
func push(src interface{}) {
select{
case <-stop:
return
default:
}
select{
case <-stop:
return
case queue <-src:
}
}
func pop() interface{}{
select{
case <-stop:
return nil
default:
}
select{
case <-stop:
return nil
case a := <-queue:
fmt.Println(a)
return a
}
}
```
首先...用go确实挺简单的...然后这里利用前一个select解决一部分select满足条件case随机选择问题...然后...比较坑的问题就来了...如果突然close(stop)肯定有一部分放到queue里,最后没有被处理...</br>
这个例子主要是说下生产者消费者逻辑,以及利用close channel当作广播使用...</br>
先写到这...</br>
```
package main
import (
"fmt"
"reflect"
"sync"
"time"
)
type _Thread struct {
Body interface{}
Args []interface{}
}
var queue = make(chan _Thread, 100)
var stop = make(chan int)
var wg = sync.WaitGroup{}
func app(a int, para, item string) {
fmt.Printf("%d; %s %s", a, para, item)
}
func sendMsg(sed _Thread) {
select {
case <-stop:
return
default:
}
select {
case <-stop:
return
case a := <- sed:
queue <- a
}
}
func main() {
go func() {
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
defer wg.Done()
for{
select {
case <-stop:
return
default:
}
select {
case v := <-queue:
if _, ok := <-stop; ok == false {
fmt.Print("stop closed")
}
obj := reflect.ValueOf(v.Body)
if obj.Kind() == reflect.Func {
params := make([]reflect.Value, len(v.Args))
for i, value := range v.Args {
params[i] = reflect.ValueOf(value)
}
obj.Call(params)
fmt.Println("jion ", i)
}
case <-stop:
return
}
}
}()
}
wg.Wait()
}()
go func(){
example := _Thread{
Body: app,
Args: []interface{}{123, "123", "456"},
}
for {
sendMsg(example)
}
}()
time.Sleep(2)
close(stop)
a := <-stop
t := make(chan int)
t <- 1
}
```
有疑问加站长微信联系(非本文作者))