package main import ( "fmt" "runtime" "time" ) //定義一個實現Job接口的數據 type Score struct { Num int } //定義對數據的處理 func (s *Score) Do() { fmt.Println("num:", s.Num) time.Sleep(500 * time.Millisecond) //模擬執行的耗時任務 } func main() { num := 100 * 100 * 2 //開啓 2萬個線程 // debug.SetMaxThreads(num + 1000) //設置最大線程數 // 註冊工作池,傳入任務 // 參數1 worker併發個數 p := NewWorkerPool(num) p.Run() //寫入一千萬條數據 dataNum := 100 * 100 * 100 * 10 go func() { for i := 1; i <= dataNum; i++ { sc := &Score{Num: i} p.JobQueue <- sc //數據傳進去會被自動執行Do()方法,具體對數據的處理自己在Do()方法中定義 } }() //循環打印輸出當前進程的Goroutine 個數 for { fmt.Println("runtime.NumGoroutine() :", runtime.NumGoroutine()) time.Sleep(5 * time.Second) } } // --------------------------- Job --------------------- type Job interface { Do() } type JobQueue chan Job // --------------------------- Worker --------------------- type Worker struct { JobChan JobQueue //每一個worker對象具有JobQueue(隊列)屬性。 } func NewWorker() Worker { return Worker{JobChan: make(chan Job)} } //啓動參與程序運行的Go程數量 func (w Worker) Run(wq chan JobQueue) { go func() { for { wq <- w.JobChan //處理任務的Go程隊列數量有限,每運行1個,向隊列中添加1個,隊列剩餘數量少1個 (JobChain入隊列) select { case job := <-w.JobChan: //fmt.Println("xxx2:",w.JobChan) job.Do() //執行操作 } } }() } // --------------------------- WorkerPool --------------------- type WorkerPool struct { //線程池: Workerlen int //線程池的大小 JobQueue JobQueue //Job隊列,接收外部的數據 WorkerQueue chan JobQueue //worker隊列:處理任務的Go程隊列 } func NewWorkerPool(workerlen int) *WorkerPool { return &WorkerPool{ Workerlen: workerlen, JobQueue: make(JobQueue), WorkerQueue: make(chan JobQueue, workerlen), } } func (wp *WorkerPool) Run() { fmt.Println("初始化worker") //初始化worker(多個Go程) for i := 0; i < wp.Workerlen; i++ { worker := NewWorker() worker.Run(wp.WorkerQueue) //開啓每一個Go程 } // 循環獲取可用的worker,往worker中寫job go func() { for { select { //將JobQueue中的數據存入WorkerQueue case job := <-wp.JobQueue: //線程池中有需要待處理的任務(數據來自於請求的任務) :讀取JobQueue中的內容 worker := <-wp.WorkerQueue //隊列中有空閒的Go程 :讀取WorkerQueue中的內容,類型爲:JobQueue worker <- job //空閒的Go程執行任務 :整個job入隊列(channel) 類型爲:傳遞的參數(Score結構體) //fmt.Println("xxx1:",worker) //fmt.Printf("====%T ; %T======\n",job,worker,) } } }() }
地址:https://blog.csdn.net/weixin_42117918/article/details/107561920