golang的高并发

栏目: Go · 发布时间: 6年前

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

几个方法

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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

思想的未来

思想的未来

(美)劳伦斯﹒莱斯格 / 李旭 / 中信出版社 / 2004-10 / 29.00元

因特网革命已到来,一些人说它已经过去,革命缘何而来?又缘何而去呢? 劳伦斯·莱斯格对因特网革命中为何会出现一种反革命的破坏性力量及后果做出了解释。创作之所以繁荣,是因为因特网保护了创新的公共资源。是因为因特网保护了创新的公共资源。因特网的独特设计营造出一个中立的平台。最广大范围的作者们可在此平台上进行试验。围绕此平台的法律架构对这一自由空间给予了保护,以使文化和信息——我们这个时代的......一起来看看 《思想的未来》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具