美文网首页
golang的高并发

golang的高并发

作者: wz998 | 来源:发表于2019-01-14 17:05 被阅读0次

几个方法

SetMaxStack设置该以被单个go程调用栈可使用的内存最大值。如果任何go程在增加其调用栈时超出了该限制,程序就会崩溃。SetMaxStack返回之前的设置。默认设置在32位系统是250MB,在64位系统是1GB。
SetMaxThreads设置go程序可以使用的最大操作系统线程数。如果程序试图使用超过该限制的线程数,就会导致程序崩溃。SetMaxThreads返回之前的设置,初始设置为10000个线程。

fmt.Println("runtime.NumCPU:", runtime.NumCPU())
fmt.Println("runtime.NumCgoCall:", runtime.NumCgoCall())
fmt.Println("runtime.NumGoroutine:", runtime.NumGoroutine())
fmt.Println("runtime.GOMAXPROCS:", runtime.GOMAXPROCS(0)) //GOMAXPROCS设置可同时执行的最大CPU数

一个例子

package main

import (
    "fmt"
    "os"
    "runtime"
    "time"
)

// SetMaxStack设置该以被单个go程调用栈可使用的内存最大值。如果任何go程在增加其调用栈时超出了该限制,程序就会崩溃。SetMaxStack返回之前的设置。默认设置在32位系统是250MB,在64位系统是1GB。
// SetMaxThreads设置go程序可以使用的最大操作系统线程数。如果程序试图使用超过该限制的线程数,就会导致程序崩溃。SetMaxThreads返回之前的设置,初始设置为10000个线程。
func main() {
    fmt.Println("runtime.NumCPU:", runtime.NumCPU())
    fmt.Println("runtime.NumCgoCall:", runtime.NumCgoCall())
    fmt.Println("runtime.NumGoroutine:", runtime.NumGoroutine())
    fmt.Println("runtime.GOMAXPROCS:", runtime.GOMAXPROCS(0)) //GOMAXPROCS设置可同时执行的最大CPU数

    NewDispatcher(1).Run()
    fmt.Println("收到 接收到红包数据 http请求")
    mtaskRequest := MtaskRequest{67}
    work := Job{MtaskRequest: mtaskRequest}
    for i := 0; i < 10; i++ {
        JobQueue <- work
    }
    time.Sleep(time.Second * 2)
    fmt.Println("runtime.NumCPU:", runtime.NumCPU())
    fmt.Println("runtime.NumCgoCall:", runtime.NumCgoCall())
    fmt.Println("runtime.NumGoroutine:", runtime.NumGoroutine())
    fmt.Println("runtime.GOMAXPROCS:", runtime.GOMAXPROCS(0))
    time.Sleep(time.Second * 100)
}

//任务的请求
type MtaskRequest struct {
    Ceshi int
    // [redacted]
}

//job队列+work池
var (
    MaxWorker = os.Getenv("MAX_WORKERS")
    MaxQueue  = os.Getenv("MAX_QUEUE")
)

// Job represents the job to be run
type Job struct {
    MtaskRequest MtaskRequest
}

// A buffered channel that we can send work requests on.

// var JobQueue chan Job ---这样申明会卡主,没有初始化
var JobQueue = make(chan Job)

// Worker represents the worker that executes the job
type Worker struct {
    WorkerPool chan chan Job
    JobChannel chan Job
    quit       chan bool
}

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

// Stop signals the worker to stop listening for work requests.
func (w Worker) Stop() {
    go func() {
        w.quit <- true
    }()
}

type Dispatcher struct {
    // A pool of workers channels that are registered with the dispatcher
    WorkerPool chan chan Job
    maxWorkers int
}

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

var num = 0

// Start method starts the run loop for the worker, listening for a quit channel in
// case we need to stop it
func (w Worker) Start() {
    go func() {
        for {
            // register the current worker into the worker queue.
            w.WorkerPool <- w.JobChannel
            select {
            case <-w.JobChannel:
                time.Sleep(1 * time.Second)
                // we have received a work request.
                num++
                fmt.Println("调起worker:", num)
            case <-w.quit:
                // we have received a signal to stop
                return
                //不能写default
            }
        }
    }()
}

func (d *Dispatcher) Run() {
    //启动一定数量的worker
    fmt.Println("启动一定数量的worker")
    for i := 0; i < d.maxWorkers; i++ {
        worker := NewWorker(d.WorkerPool)
        worker.Start()
    }

    go d.dispatch()
}

var num2 = 0

//分派任务
func (d *Dispatcher) dispatch() {
    for {
        select {
        case job := <-JobQueue: //接收一个job请求
            num2++
            fmt.Println("JobQueue 收到请求:", num2)
            // jobChannel := <-d.WorkerPool
            // // dispatch the job to the worker job channel
            // jobChannel <- job
            go func(job Job) {
                // try to obtain a worker job channel that is available.
                // this will block until a worker is idle
                jobChannel := <-d.WorkerPool
                // dispatch the job to the worker job channel
                jobChannel <- job
            }(job)
        }
    }
}

// //接收到红包数据
// func (this *TaskRedbao) UserGetRedbao(red_id, uid, shop_id, rand_arr, Amoney string) error {
//  fmt.Println("收到 接收到红包数据 http请求")
//  mtaskRequest := MtaskRequest{67}
//  work := Job{MtaskRequest: mtaskRequest}

//  JobQueue <- work
//  return nil
// }

转载自 https://blog.csdn.net/jzbis/article/details/83066127

相关文章

  • golang的高并发

    几个方法 SetMaxStack设置该以被单个go程调用栈可使用的内存最大值。如果任何go程在增加其调用栈时超出了...

  • Golang对象复用静态代码检查工具

    一、对象复用 在高并发的场景下使用golang,优化GC都会无法回避的问题。搜索「golang 垃圾回收优化」出来...

  • Go goroutine

    Golang特色之一是支持高并发编程模型,以Goroutine作为基本的并发执行单元。 Goroutine是轻量级...

  • RxJava2+Retrofit2+golang

    说在前面 本人能力有限,望高手勿喷。 golang golang语言又叫go语言,是google公司为了适应高并发...

  • Go每日精选(2019-06-27)

    1.Golang 大杀器之性能剖析 PProf 2.Kafka 集群 Golang 应用实例 3.高并发下如何缩短...

  • Golang的并发编程

    golang是为并发而生的语言。优雅的并发编程范式,完善的并发支持,出色的并发性能是golang区别于其他语言的一...

  • go

    我们使用golang构建websocket,支持高性能、高并发,websocket不用多介绍,go自带原生webs...

  • golang语言map的并发和排序

    golang语言map的并发和排序 map的并发问题 golang缺省的map不是thread safe的,如果存...

  • Golang高并发工作池

    go程序开发过程中,通过简单的调用go func 函数来开启协程,容易导致程序死锁,并且会无限制的开启grouti...

  • Go append并发问题

    Golang append并发问题

网友评论

      本文标题:golang的高并发

      本文链接:https://www.haomeiwen.com/subject/cjjjdqtx.html