{"id":199887,"date":"2020-11-11T09:05:21","date_gmt":"2020-11-11T01:05:21","guid":{"rendered":"http:\/\/4563.org\/?p=199887"},"modified":"2020-11-11T09:05:21","modified_gmt":"2020-11-11T01:05:21","slug":"go-%e5%8d%8f%e7%a8%8b%e6%b1%a0%e8%a7%a3%e6%9e%90%e9%80%9a%e4%bf%97%e6%98%93%e6%87%82","status":"publish","type":"post","link":"http:\/\/4563.org\/?p=199887","title":{"rendered":"Go \u534f\u7a0b\u6c60\u89e3\u6790~\u901a\u4fd7\u6613\u61c2"},"content":{"rendered":"<div>\n<div>\n<div>\n<h1>                  Go \u534f\u7a0b\u6c60\u89e3\u6790~\u901a\u4fd7\u6613\u61c2               <\/h1>\n<p> <\/p>\n<div>\n<div> <span>\u8cc7\u6df1\u5927\u4f6c : sunshinev <\/span>  <span><i><\/i> 6<\/span> <\/div>\n<div> <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<div isfirst=\"1\"> <\/p>\n<p>\u534f\u7a0b\u6c60\u4e3b\u8981\u662f\u4e3a\u4e86\u51cf\u5c11 go \u534f\u7a0b\u9891\u7e41\u521b\u5efa\u3001\u9500\u6bc1\u5e26\u6765\u7684\u6027\u80fd\u635f\u8017\uff0c\u867d\u7136\u53ef\u4ee5\u5ffd\u7565\u4e0d\u8ba1\uff0c\u4f46\u662f\u7f51\u4e0a\u8bf4\u7279\u6b8a\u60c5\u51b5\u8fd8\u662f\u6709\u7528\u7684\u3002<\/p>\n<p>\u90a3\u8fd9\u4e2a\u534f\u7a0b\u6c60\u901a\u4fd7\u6613\u61c2\u6765\u8bb2\uff0c\u6bd4\u5982\u8001\u677f\u7ed9\u5458\u5de5\u5206\u914d\u4efb\u52a1\uff1a<\/p>\n<p>\u8001\u677f\u9886\u4e86\u4e00\u5806\u4efb\u52a1\uff0c\u5f97\u627e\u5de5\u4eba\u5e72\u6d3b\u5440\uff0c \u90a3\u9886\u5bfc\u5c31\u62ff\u51fa\u4e00\u4e2a\u4efb\u52a1\uff0c\u7ed9\u4e00\u4e2a\u7a7a\u95f2\u7684\u5458\u5de5 A\uff0c\u518d\u628a\u4e0b\u4e00\u4e2a\u4efb\u52a1\uff0c\u7ed9\u53e6\u5916\u4e00\u4e2a\u7a7a\u95f2\u7684\u5458\u5de5 B \u3002<\/p>\n<p>\u8fd9\u65f6\u5019 A \u6216\u8005 B\uff0c\u6307\u4e0d\u5b9a\u8c01\u5148\u5fd9\u5b8c\u4e86<\/p>\n<p>\u5982\u679c\u6709\u4eba\u5fd9\u5b8c\u4e86\uff0c\u9886\u5bfc\u5c31\u628a\u4e0b\u4e00\u4e2a\u4efb\u52a1\uff0c\u7ed9\u5148\u5fd9\u5b8c\u7684\u4eba\u3002A\/B \u5c31\u662f\u534f\u7a0b\u6c60\u91cc\u9762\u7684\u4e24\u4e2a\u534f\u7a0b<\/p>\n<p>\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u5b8c\u6210\u4e86\u5982\u4e0b\u529f\u80fd<\/p>\n<ol>\n<li>\u534f\u7a0b\u6c60\u6570\u91cf\u4e0a\u9650\u63a7\u5236<\/li>\n<li>\u534f\u7a0b\u7a7a\u95f2\u6e05\u7406\uff0c\u91ca\u653e\u5185\u5b58<\/li>\n<li>\u534f\u7a0b\u590d\u7528<\/li>\n<\/ol>\n<pre><code>package gopool  import (  \"context\"  \"log\"  \"sync\"  \"time\" )  type Task func()  \/\/ boss \u8001\u677f type GoPool struct {  MaxWorkerIdleTime time.Duration \/\/ worker \u6700\u5927\u7a7a\u95f2\u65f6\u95f4  MaxWorkerNum      int32         \/\/ \u534f\u7a0b\u6700\u5927\u6570\u91cf  TaskEntryChan     chan *Task    \/\/ \u4efb\u52a1\u5165\u5217  Workers           []*worker     \/\/ \u5df2\u521b\u5efa worker  FreeWorkerChan    chan *worker  \/\/ \u7a7a\u95f2 worker  Lock              sync.Mutex }  const (  WorkerStatusStop = 1  WorkerStatusLive = 0 )  \/\/ \u5e72\u6d3b\u7684\u4eba type worker struct {  Pool         *GoPool  StartTime    time.Time  \/\/ \u5f00\u59cb\u65f6\u95f4  TaskChan     chan *Task \/\/ \u6267\u884c\u961f\u5217  LastWorkTime time.Time  \/\/ \u6700\u540e\u6267\u884c\u65f6\u95f4  Ctx          context.Context  Cancel       context.CancelFunc  Status       int32 \/\/ \u88ab\u8fc7\u671f\u5220\u6389\u7684\u6807\u8bb0 }  var defaultPool = func() *GoPool {  return NewPool() }()  \/\/ \u521d\u59cb\u5316 func NewPool() *GoPool {  g := &amp;GoPool{   MaxWorkerIdleTime: 10 * time.Second,   MaxWorkerNum:      20,   TaskEntryChan:     make(chan *Task, 2000),   FreeWorkerChan:    make(chan *worker, 2000),  }   \/\/ \u5206\u53d1\u4efb\u52a1  go g.dispatchTask()   \/\/\u6e05\u7406\u7a7a\u95f2 worker  go g.fireWorker()   return g }  \/\/ \u5b9a\u671f\u6e05\u7406\u7a7a\u95f2 worker func (g *GoPool) fireWorker() {  for {   select {   \/\/ 10 \u79d2\u6267\u884c\u4e00\u6b21   case &lt;-time.After(10 * time.Second):    for k, w := range g.Workers {     if time.Now().Sub(w.LastWorkTime) &gt; g.MaxWorkerIdleTime {      log.Printf(\"overtime %v %p\", k, w)      \/\/ \u7ec8\u6b62\u534f\u7a0b      w.Cancel()      \/\/ \u6e05\u7406 Free      w.Status = WorkerStatusStop     }    }     g.Lock.Lock()    g.Workers = g.cleanWorker(g.Workers)    g.Lock.Unlock()   }  } }  \/\/ \u9012\u5f52\u6e05\u7406\u65e0\u7528 worker func (g *GoPool) cleanWorker(workers []*worker) []*worker {  for k, w := range workers {   if time.Now().Sub(w.LastWorkTime) &gt; g.MaxWorkerIdleTime {    workers = append(workers[:k], workers[k+1:]...) \/\/ \u5220\u9664\u4e2d\u95f4 1 \u4e2a\u5143\u7d20    return g.cleanWorker(workers)   }  }   return workers }  \/\/ \u5206\u53d1\u4efb\u52a1 func (g *GoPool) dispatchTask() {   for {   select {   case t := &lt;-g.TaskEntryChan:    log.Printf(\"dispatch task %p\", t)    \/\/ \u83b7\u53d6 worker    w := g.fetchWorker()    \/\/ \u5c06\u4efb\u52a1\u6254\u7ed9 worker    w.accept(t)   }  } }  \/\/ \u83b7\u53d6\u53ef\u7528 worker func (g *GoPool) fetchWorker() *worker {  for {   select {   \/\/ \u83b7\u53d6\u7a7a\u95f2 worker   case w := &lt;-g.FreeWorkerChan:    if w.Status == WorkerStatusLive {     return w    }   default:    \/\/ \u521b\u5efa\u65b0\u7684 worker    if int32(len(g.Workers)) &lt; g.MaxWorkerNum {     w := &amp;worker{      Pool:         g,      StartTime:    time.Now(),      LastWorkTime: time.Now(),      TaskChan:     make(chan *Task, 1),      Ctx:          context.Background(),      Status:       WorkerStatusLive,     }     ctx, cancel := context.WithCancel(w.Ctx)      w.Cancel = cancel     \/\/ \u63a5\u5230\u4efb\u52a1\u81ea\u5df1\u53bb\u6267\u884c\u5427     go w.execute(ctx)      g.Lock.Lock()     g.Workers = append(g.Workers, w)     g.Lock.Unlock()      g.FreeWorkerChan &lt;- w      log.Printf(\"worker create %p\", w)    }   }  } }  \/\/ \u6dfb\u52a0\u4efb\u52a1 func (g *GoPool) addTask(t Task) {  \/\/ \u5c06\u4efb\u52a1\u653e\u5230\u5165\u53e3\u4efb\u52a1\u961f\u5217  g.TaskEntryChan &lt;- &amp;t }  \/\/ \u63a5\u53d7\u4efb\u52a1 func (w *worker) accept(t *Task) {  \/\/ \u6bcf\u4e2a worker \u81ea\u5df1\u7684\u5de5\u4f5c\u961f\u5217  w.TaskChan &lt;- t }  \/\/ \u6267\u884c\u4efb\u52a1 func (w *worker) execute(ctx context.Context) {  for {   select {   case t := &lt;-w.TaskChan:    \/\/ \u6267\u884c    (*t)()    \/\/ \u8bb0\u5f55\u5de5\u4f5c\u72b6\u6001    w.LastWorkTime = time.Now()    w.Pool.FreeWorkerChan &lt;- w   case &lt;-ctx.Done():    log.Printf(\"worker done %p\", w)    return   }  } }  \/\/ \u6267\u884c func SafeGo(t Task) {  defaultPool.addTask(t) }  <\/code><\/pre>\n<\/p><\/div>\n<div> <b>\u5927\u4f6c\u6709\u8a71\u8aaa<\/b> (<span>4<\/span>)        <\/div>\n<div> <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<ul>\n<li data-pid=\"4272340\" data-uid=\"2\">\n<div>\n<div>\n<div> <span>\u8cc7\u6df1\u5927\u4f6c : pabupa <\/span>  <\/div>\n<div> <i title=\"\u5f15\u7528\"><\/i>  <span>          <\/span> <\/div>\n<\/p><\/div>\n<div>                                                             \u8d8a\u4fce\u4ee3\u5e96                                                            <\/div>\n<\/p><\/div>\n<\/li>\n<li data-pid=\"4272341\" data-uid=\"2\">\n<div>\n<div>\n<div> <span>\u8cc7\u6df1\u5927\u4f6c : fuis <\/span>  <\/div>\n<div> <i title=\"\u5f15\u7528\"><\/i>  <span>          <\/span> <\/div>\n<\/p><\/div>\n<div>                                                             \u8131\u88e4\u5b50\u653e\u5c41                                                            <\/div>\n<\/p><\/div>\n<\/li>\n<li data-pid=\"4272342\" data-uid=\"2\">\n<div>\n<div>\n<div> <span>\u8cc7\u6df1\u5927\u4f6c : Weixiao0725 <\/span>  <\/div>\n<div> <i title=\"\u5f15\u7528\"><\/i>  <span>          <\/span> <\/div>\n<\/p><\/div>\n<div>                                                             \u53ef\u80fd\u534f\u7a0b\u6bd4\u7ebf\u7a0b\u8f7b\u91cf\uff0c\u4e0d\u9700\u8981\u6c60\u5b50\u7f13\u5b58\uff1f                                                            <\/div>\n<\/p><\/div>\n<\/li>\n<li data-pid=\"4272343\" data-uid=\"2\">\n<div>\n<div>\n<div> <span>\u8cc7\u6df1\u5927\u4f6c : koujyungenn <\/span>  <\/div>\n<div> <i title=\"\u5f15\u7528\"><\/i>  <span>          <\/span> <\/div>\n<\/p><\/div>\n<div>                                                             \u4e0d\u61c2\u5c31\u95ee\uff0c\u534f\u7a0b\u6c60\u6709\u4ec0\u4e48\u5e94\u7528\u573a\u666f\uff1f                                                            <\/div>\n<\/p><\/div>\n<\/li>\n<li>\n","protected":false},"excerpt":{"rendered":"<p>Go \u534f\u7a0b\u6c60\u89e3\u6790~\u901a\u4fd7\u6613\u61c2 \u8cc7\u6df1\u5927&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[],"tags":[],"_links":{"self":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts\/199887"}],"collection":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=199887"}],"version-history":[{"count":0,"href":"http:\/\/4563.org\/index.php?rest_route=\/wp\/v2\/posts\/199887\/revisions"}],"wp:attachment":[{"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=199887"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=199887"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/4563.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=199887"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}