golang---并发(摘抄)

1. 事例

package main

import (
	"fmt"
	"net/http"
	"os"
	"runtime"
)

var (
	//Max_Num = os.Getenv("MAX_NUM")
	MaxWorker = runtime.NumCPU()
	MaxQueue  = 1000
)

type Serload struct {
	pri string
}

type Job struct {
	serload Serload
}

var JobQueue chan Job

type Worker struct {
	WorkerPool chan chan Job
	JobChannel chan Job
	Quit       chan bool
}

func NewWorker(workPool chan chan Job) Worker {
	return Worker{
		WorkerPool: workPool,
		JobChannel: make(chan Job),
		Quit:       make(chan bool),
	}
}

func (w Worker) Start() {
	go func() {
		for {
			w.WorkerPool <- w.JobChannel
			select {
			case job := <-w.JobChannel:
				// excute job
				fmt.Println(job.serload.pri)
			case <-w.Quit:
				return
			}
		}
	}()
}

func (w Worker) Stop() {
	go func() {
		w.Quit <- true
	}()
}

type Dispatcher struct {
	MaxWorkers int
	WorkerPool chan chan Job
	Quit       chan bool
}

func NewDispatcher(maxWorkers int) *Dispatcher {
	pool := make(chan chan Job, maxWorkers)
	return &Dispatcher{MaxWorkers: maxWorkers, WorkerPool: pool, Quit: make(chan bool)}
}

func (d *Dispatcher) Run() {
	for i := 0; i < d.MaxWorkers; i++ {
		worker := NewWorker(d.WorkerPool)
		worker.Start()
	}

	go d.Dispatch()
}

func (d *Dispatcher) Stop() {
	go func() {
		d.Quit <- true
	}()
}

func (d *Dispatcher) Dispatch() {
	for {
		select {
		case job := <-JobQueue:
			go func(job Job) {
				jobChannel := <-d.WorkerPool
				jobChannel <- job
			}(job)
		case <-d.Quit:
			return
		}
	}
}

func entry(res http.ResponseWriter, req *http.Request) {
	// fetch job
	work := Job{serload: Serload{pri: "Just do it"}}
	JobQueue <- work
	fmt.Fprintf(res, "Hello World ...again")
}

func init() {
	runtime.GOMAXPROCS(MaxWorker)
	JobQueue = make(chan Job, MaxQueue)
	dispatcher := NewDispatcher(MaxWorker)
	dispatcher.Run()
}

func main() {
	Port := "8086"
	IsHttp := true
	arg_num := len(os.Args)

	if 2 <= arg_num {
		Port = os.Args[1]
	}

	if 3 <= arg_num {
		if os.Args[2] == "true" {
			IsHttp = true
		} else {
			IsHttp = false
		}
	}

	fmt.Printf("server is http %t\n", IsHttp)
	fmt.Println("server listens at ", Port)

	http.HandleFunc("/", entry)

	var err error
	if IsHttp {
		err = http.ListenAndServe(":"+Port, nil)
	} else {
		err = http.ListenAndServeTLS(":"+Port, "server.crt", "server.key", nil)
	}

	if err != nil {
		fmt.Println("Server failure /// ", err)
	}

	fmt.Println("quit")
}

结合这个来理解chan chan

2. 参考

https://studygolang.com/articles/22681
http://tleyden.github.io/blog/2013/11/23/understanding-chan-chans-in-go/
https://segmentfault.com/a/1190000017958702#item-13 (chan chan)
https://github.com/rubyhan1314/Golang-100-Days/blob/master/Day16-20(Go语言基础进阶)/day17_Go语言并发Goroutine.md
https://learnku.com/go/t/39490
https://chai2010.gitbooks.io/advanced-go-programming-book/content/ch1-basic/ch1-06-goroutine.html

https://github.com/double12gzh/golang_step_by_step

3. 代码示例

posted @ 2020-03-15 13:26  大海星  阅读(228)  评论(0编辑  收藏  举报