{"id":60,"date":"2018-12-19T18:48:41","date_gmt":"2018-12-19T10:48:41","guid":{"rendered":"https:\/\/chenqinghe.com\/?p=60"},"modified":"2019-10-22T13:56:50","modified_gmt":"2019-10-22T05:56:50","slug":"go%e6%9d%a1%e4%bb%b6%e5%8f%98%e9%87%8fsync-cond%e8%af%a6%e8%a7%a3","status":"publish","type":"post","link":"https:\/\/chenqinghe.com\/?p=60","title":{"rendered":"Go\u6761\u4ef6\u53d8\u91cfsync.Cond\u8be6\u89e3"},"content":{"rendered":"<section id=\"output_wrapper_id\" class=\"output_wrapper\">\n<section id=\"output_wrapper_id\" class=\"output_wrapper\">\u6700\u8fd1\u9047\u5230\u4e00\u4e2a\u8fd9\u6837\u7684\u573a\u666f\uff1a\u5f53\u67d0\u4e2a\u6761\u4ef6\u6216\u8005\u4efb\u52a1\u5b8c\u6210\u4e86\u4e4b\u540e\uff0c\u901a\u77e5\u5176\u4ed6\u7b49\u5f85\u7684\u5404\u4e2a\u201c\u5b88\u62a4goroutine\u201d\uff08\u5373\u6b7b\u5faa\u73af\u6267\u884c\u67d0\u9879\u4efb\u52a1\u7684goroutine\uff09\u7ee7\u7eed\u6267\u884c\u3002\u9996\u5148\u60f3\u5230\u7684\u662f\u4f7f\u7528channel\u6765\u5b8c\u6210\uff0c\u7136\u800cchannel\u6709\u4e00\u5b9a\u7684\u5c40\u9650\u6027\u3002\u9996\u5148\uff0cchannel\u6bd4\u8f83\u9002\u7528\u4e8e\u4e00\u5bf9\u4e00\uff0c\u5f3a\u884c\u4e00\u5bf9\u591a\u7684\u8bdd\u6bd4\u8f83\u96be\u53d7\uff0c\u4e0d\u8fc7\u4e5f\u53ef\u4ee5\u4f7f\u7528close\u5173\u95edchannel\u6765\u8fbe\u5230\u901a\u77e5\u6240\u6709\u7684receiver\u7684\u76ee\u7684\uff0c\u4f46\u662f\u8fd9\u79cd\u65b9\u6cd5\u4e0d\u80fd\u591f\u591a\u6b21\u4f7f\u7528\uff0c\u5c31\u662f\u4e00\u65e6channel\u5173\u95ed\u4e86\u4e4b\u540e\u518d\u6b21\u5173\u95ed\uff0c\u4f1a\u76f4\u63a5panic\u3002\u53e6\u5916\u4e00\u79cd\u65b9\u5f0f\u5c31\u662fgo\u6807\u51c6\u5e93\u4e2d\u63d0\u4f9b\u7684sync.Cond\u4e86\u3002\u5728\u4f7f\u7528\u7684\u8fc7\u7a0b\u4e2d\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u4e24\u4e2a\u7591\u95ee\uff1a<\/p>\n<ol>\n<li>Signal()\u65b9\u6cd5\uff0c\u53d1\u51fa\u4fe1\u53f7\u540e\uff0c\u63a5\u6536\u5230\u7684goroutine\u662f\u968f\u673a\u7684\u5417\uff1f<\/li>\n<li>sync.Cond\u4e2d\u7684L\u9501\u662f\u9501\u4ec0\u4e48\u7684\uff1f\u4e3a\u4ec0\u4e48\u8981\u6709\u8fd9\u4e2a\uff1f<\/li>\n<\/ol>\n<p>\u7ffb\u4e86\u4e0b\u6e90\u7801\u4e4b\u540e\uff0c\u5927\u81f4\u7406\u89e3\u4e86\uff0c\u5728\u6b64\u505a\u4e2a\u8bb0\u5f55\u3002<\/p>\n<h3 id=\"hsynccond\">sync.Cond\u4ecb\u7ecd<\/h3>\n<p>sync.Cond\u662f\u4e00\u4e2a\u7ed3\u6784\u4f53\uff0c\u5176\u7ed3\u6784\u975e\u5e38\u7b80\u5355\uff1a<\/p>\n<pre><code class=\"GO language-GO hljs\"><span class=\"linenum hljs-number\">1<\/span><span class=\"hljs-keyword\">type<\/span>\u00a0Cond\u00a0<span class=\"hljs-keyword\">struct<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">2<\/span>\u00a0\u00a0\u00a0\u00a0noCopy\u00a0noCopy\r\n<span class=\"linenum hljs-number\">3<\/span>\r\n<span class=\"linenum hljs-number\">4<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0L\u00a0is\u00a0held\u00a0while\u00a0observing\u00a0or\u00a0changing\u00a0the\u00a0condition<\/span>\r\n<span class=\"linenum hljs-number\">5<\/span>\u00a0\u00a0\u00a0\u00a0L\u00a0Locker\r\n<span class=\"linenum hljs-number\">6<\/span>\r\n<span class=\"linenum hljs-number\">7<\/span>\u00a0\u00a0\u00a0\u00a0notify\u00a0\u00a0notifyList\r\n<span class=\"linenum hljs-number\">8<\/span>\u00a0\u00a0\u00a0\u00a0checker\u00a0copyChecker\r\n<span class=\"linenum hljs-number\">9<\/span>}\r\n<\/code><\/pre>\n<p>\u5176\u4e2dnoCopy\u548cchecker\u662f\u4e3a\u4e86\u9632\u6b62\u53d8\u91cf\u62f7\u8d1d\u7684\uff0c\u5728sync.Cond\u7684\u4f7f\u7528\u8fc7\u7a0b\u4e2d\u662f\u7981\u6b62\u62f7\u8d1d\u53d8\u91cf\u7684\uff0c\u672c\u6587\u6682\u4e14\u4e0d\u8bf4\u3002L\u662f\u9501\uff0c\u5177\u4f53\u9501\u4ec0\u4e48\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u8981\u6709\u9501\uff0c\u6211\u4eec\u540e\u9762\u518d\u8bf4\u3002notify\u662f\u4e00\u4e2a\u901a\u77e5\u7684\u5217\u8868\uff0c\u4fdd\u5b58\u4e86\u6240\u6709\u8c03\u7528\u4e86Wait()\u7684goroutine\u3002\u5176\u5b9a\u4e49\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"Go language-Go hljs\"><span class=\"linenum hljs-number\">1<\/span><span class=\"hljs-comment\">\/\/\u00a0Approximation\u00a0of\u00a0notifyList\u00a0in\u00a0runtime\/sema.go.\u00a0Size\u00a0and\u00a0alignment\u00a0must<\/span>\r\n<span class=\"linenum hljs-number\">2<\/span><span class=\"hljs-comment\">\/\/\u00a0agree.<\/span>\r\n<span class=\"linenum hljs-number\">3<\/span><span class=\"hljs-keyword\">type<\/span>\u00a0notifyList\u00a0<span class=\"hljs-keyword\">struct<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">4<\/span>\u00a0\u00a0\u00a0\u00a0wait\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">uint32<\/span>\r\n<span class=\"linenum hljs-number\">5<\/span>\u00a0\u00a0\u00a0\u00a0notify\u00a0<span class=\"hljs-keyword\">uint32<\/span>\r\n<span class=\"linenum hljs-number\">6<\/span>\u00a0\u00a0\u00a0\u00a0lock\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">uintptr<\/span>\r\n<span class=\"linenum hljs-number\">7<\/span>\u00a0\u00a0\u00a0\u00a0head\u00a0\u00a0\u00a0unsafe.Pointer\r\n<span class=\"linenum hljs-number\">8<\/span>\u00a0\u00a0\u00a0\u00a0tail\u00a0\u00a0\u00a0unsafe.Pointer\r\n<span class=\"linenum hljs-number\">9<\/span>}\r\n<\/code><\/pre>\n<p>\u4f46\u5177\u4f53\u7684\u771f\u5b9e\u5b9e\u73b0\uff0c\u5176\u5b9e\u662f\u5728runtime\/sema.go\u4e2d\uff0c\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\">1<\/span><span class=\"hljs-keyword\">type<\/span>\u00a0notifyList\u00a0<span class=\"hljs-keyword\">struct<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">2<\/span>\u00a0\u00a0\u00a0\u00a0wait\u00a0<span class=\"hljs-keyword\">uint32<\/span>\r\n<span class=\"linenum hljs-number\">3<\/span>\r\n<span class=\"linenum hljs-number\">4<\/span>\u00a0\u00a0\u00a0\u00a0notify\u00a0<span class=\"hljs-keyword\">uint32<\/span>\r\n<span class=\"linenum hljs-number\">5<\/span>\r\n<span class=\"linenum hljs-number\">6<\/span>\u00a0\u00a0\u00a0\u00a0lock\u00a0mutex\r\n<span class=\"linenum hljs-number\">7<\/span>\u00a0\u00a0\u00a0\u00a0head\u00a0*sudog\r\n<span class=\"linenum hljs-number\">8<\/span>\u00a0\u00a0\u00a0\u00a0tail\u00a0*sudog\r\n<span class=\"linenum hljs-number\">9<\/span>}\r\n<\/code><\/pre>\n<p>wait\u548cnotify\u662f\u4e24\u4e2a\u6807\u8bc6\uff0c\u6bcf\u6b21\u8c03\u7528cond.Wait()\u65b9\u6cd5\u65f6\uff0cwait\u81ea\u589e1\uff0c\u5e76\u628a\u81ea\u589e\u540e\u7684\u503c\u8fd4\u56de\u7ed9\u8c03\u7528\u65b9\uff0c\u6bcf\u6b21\u8c03\u7528cond.Signal()\u6216\u8005cond.Broadcast()\u65f6\uff0cnotify\u4f1a\u81ea\u589e\u3002\u5f53wait\u503c\u5927\u4e8enotify\u7684\u503c\u65f6\uff0c\u8bf4\u660e\u6709\u672a\u88ab\u5524\u9192\u7684goroutine\uff1b\u5f53\u4e24\u8005\u76f8\u7b49\u65f6\uff0c\u8bf4\u660e\u5747\u5df2\u88ab\u5524\u9192\uff1b\u5f53\u7136\uff0c\u4e0d\u5b58\u5728notify&gt;wait\u7684\u60c5\u51b5\u3002<\/p>\n<p>\u4e0b\u9762\u6765\u770b\u4e00\u4e0bsync.Cond\u63d0\u4f9b\u7684\u51fd\u6570\u4ee5\u53ca\u662f\u5982\u4f55\u4f7f\u7528\u4e0a\u9762\u7684\u8fd9\u4e9b\u7ed3\u6784\u7684\u3002\u5176api\u4e5f\u662f\u5f88\u7b80\u5355\u7684\uff0c\u53ea\u6709\u4e09\u4e2a\u65b9\u6cd5\u3002<\/p>\n<h4 id=\"hwait\">Wait<\/h4>\n<p>Wait\u65b9\u6cd5\u662f\u963b\u585e\u5f53\u524d\u8fd0\u884c\u7684goroutine\uff0c\u76f4\u81f3\u5176\u4ed6goroutine\u5c06\u5b83\u5524\u9192\u624d\u80fd\u591f\u7ee7\u7eed\u6267\u884c\u3002<\/p>\n<pre><code class=\"Go language-Go hljs\"><span class=\"linenum hljs-number\">1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-params\">(c\u00a0*Cond)<\/span>\u00a0<span class=\"hljs-title\">Wait<\/span><span class=\"hljs-params\">()<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">2<\/span>\u00a0\u00a0\u00a0\u00a0c.checker.check()\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u68c0\u67e5\u662f\u5426\u6709\u62f7\u8d1d<\/span>\r\n<span class=\"linenum hljs-number\">3<\/span>\u00a0\u00a0\u00a0\u00a0t\u00a0:=\u00a0runtime_notifyListAdd(&amp;c.notify)\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u81ea\u589enotify\u53d8\u91cf<\/span>\r\n<span class=\"linenum hljs-number\">4<\/span>\u00a0\u00a0\u00a0\u00a0c.L.Unlock()\u00a0\u00a0\r\n<span class=\"linenum hljs-number\">5<\/span>\u00a0\u00a0\u00a0\u00a0runtime_notifyListWait(&amp;c.notify,\u00a0t)\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u5c06\u5f53\u524dgoroutine\u6302\u8d77<\/span>\r\n<span class=\"linenum hljs-number\">6<\/span>\u00a0\u00a0\u00a0\u00a0c.L.Lock()\u00a0\r\n<span class=\"linenum hljs-number\">7<\/span>}\r\n<\/code><\/pre>\n<p>Wait\u65b9\u6cd5\u9996\u5148\u8fdb\u884c\u62f7\u8d1d\u68c0\u67e5\uff0c\u7136\u540e\u5bf9notify\u7ed3\u6784\u4e2d\u7684wait\u53d8\u91cf\u8fdb\u884c\u81ea\u589e+1\u3002\u6b64\u64cd\u4f5c\u662f\u539f\u5b50\u6027\u7684\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\">1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-title\">notifyListAdd<\/span><span class=\"hljs-params\">(l\u00a0*notifyList)<\/span>\u00a0<span class=\"hljs-title\">uint32<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">2<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0This\u00a0may\u00a0be\u00a0called\u00a0concurrently,\u00a0for\u00a0example,\u00a0when\u00a0called\u00a0from<\/span>\r\n<span class=\"linenum hljs-number\">3<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0sync.Cond.Wait\u00a0while\u00a0holding\u00a0a\u00a0RWMutex\u00a0in\u00a0read\u00a0mode.<\/span>\r\n<span class=\"linenum hljs-number\">4<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span>\u00a0atomic.Xadd(&amp;l.wait,\u00a0<span class=\"hljs-number\">1<\/span>)\u00a0-\u00a0<span class=\"hljs-number\">1<\/span>\r\n<span class=\"linenum hljs-number\">5<\/span>}\r\n<\/code><\/pre>\n<p>\u7136\u540e\u662fruntime_notifyListWait(&amp;c.notify, t),\u6765\u770b\u4e0b\u6b64\u51fd\u6570\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\uff1a<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\"> 1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-title\">notifyListWait<\/span><span class=\"hljs-params\">(l\u00a0*notifyList,\u00a0t\u00a0<span class=\"hljs-keyword\">uint32<\/span>)<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\"> 2<\/span>\u00a0\u00a0\u00a0\u00a0lock(&amp;l.lock)\r\n<span class=\"linenum hljs-number\"> 3<\/span>\r\n<span class=\"linenum hljs-number\"> 4<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0Return\u00a0right\u00a0away\u00a0if\u00a0this\u00a0ticket\u00a0has\u00a0already\u00a0been\u00a0notified.<\/span>\r\n<span class=\"linenum hljs-number\"> 5<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0less(t,\u00a0l.notify)\u00a0{\r\n<span class=\"linenum hljs-number\"> 6<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unlock(&amp;l.lock)\r\n<span class=\"linenum hljs-number\"> 7<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span>\r\n<span class=\"linenum hljs-number\"> 8<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\"> 9<\/span>\r\n<span class=\"linenum hljs-number\">10<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0Enqueue\u00a0itself.<\/span>\r\n<span class=\"linenum hljs-number\">11<\/span>\u00a0\u00a0\u00a0\u00a0s\u00a0:=\u00a0acquireSudog()\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u83b7\u53d6sudog<\/span>\r\n<span class=\"linenum hljs-number\">12<\/span>\u00a0\u00a0\u00a0\u00a0s.g\u00a0=\u00a0getg()\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u83b7\u53d6g<\/span>\r\n<span class=\"linenum hljs-number\">13<\/span>\u00a0\u00a0\u00a0\u00a0s.ticket\u00a0=\u00a0t\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u5c06wait\u503c\u653e\u5165sudog\u4e2d\uff0c\u540e\u7eed\u67e5\u627e\u7528<\/span>\r\n<span class=\"linenum hljs-number\">14<\/span>\u00a0\u00a0\u00a0\u00a0s.releasetime\u00a0=\u00a0<span class=\"hljs-number\">0<\/span>\r\n<span class=\"linenum hljs-number\">15<\/span>\u00a0\u00a0\u00a0\u00a0t0\u00a0:=\u00a0<span class=\"hljs-keyword\">int64<\/span>(<span class=\"hljs-number\">0<\/span>)\r\n<span class=\"linenum hljs-number\">16<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0blockprofilerate\u00a0&gt;\u00a0<span class=\"hljs-number\">0<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">17<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0t0\u00a0=\u00a0cputicks()\r\n<span class=\"linenum hljs-number\">18<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0s.releasetime\u00a0=\u00a0<span class=\"hljs-number\">-1<\/span>\r\n<span class=\"linenum hljs-number\">19<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">20<\/span>\r\n<span class=\"linenum hljs-number\">21<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u5c06sudog\u653e\u5165\u94fe\u8868\u5c3e<\/span>\r\n<span class=\"linenum hljs-number\">22<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0l.tail\u00a0==\u00a0<span class=\"hljs-literal\">nil<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">23<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.head\u00a0=\u00a0s\r\n<span class=\"linenum hljs-number\">24<\/span>\u00a0\u00a0\u00a0\u00a0}\u00a0<span class=\"hljs-keyword\">else<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">25<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.tail.next\u00a0=\u00a0s\r\n<span class=\"linenum hljs-number\">26<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">27<\/span>\u00a0\u00a0\u00a0\u00a0l.tail\u00a0=\u00a0s\r\n<span class=\"linenum hljs-number\">28<\/span>\r\n<span class=\"linenum hljs-number\">29<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u5c06\u5f53\u524dg\u653e\u5165\u5f85\u6267\u884c\u961f\u5217<\/span>\r\n<span class=\"linenum hljs-number\">30<\/span>\u00a0\u00a0\u00a0\u00a0goparkunlock(&amp;l.lock,\u00a0waitReasonSyncCondWait,\u00a0traceEvGoBlockCond,\u00a0<span class=\"hljs-number\">3<\/span>)\r\n<span class=\"linenum hljs-number\">31<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0t0\u00a0!=\u00a0<span class=\"hljs-number\">0<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">32<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0blockevent(s.releasetime-t0,\u00a0<span class=\"hljs-number\">2<\/span>)\r\n<span class=\"linenum hljs-number\">33<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">34<\/span>\u00a0\u00a0\u00a0\u00a0releaseSudog(s)\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u5c06sudog\u653e\u56de\u8d44\u6e90\u6c60<\/span>\r\n<span class=\"linenum hljs-number\">35<\/span>}\r\n<\/code><\/pre>\n<p>\u9996\u5148\u6bd4\u8f83\u4e86\u4e0a\u4e00\u6b65\u81ea\u589e\u540e\u7684wait\u548cnofify\u53d8\u91cf\uff0c\u5982\u679c\u5c0f\u4e8e\uff0c\u90a3\u4e48\u8bf4\u660e\u5df2\u7ecf\u88ab\u901a\u77e5\u8fc7\u4e86\uff0c\u53ef\u4ee5\u76f4\u63a5\u8fd4\u56de\u3002<br \/>\n\u7136\u540e\u662f\u4ece\u8d44\u6e90\u6c60\u4e2d\u83b7\u53d6sudog\u548c\u5f53\u524d\u7684g(\u5173\u4e8e\u8c03\u5ea6\u5668\u4e2dm\u3001p\u3001g\u53ca\u4e09\u8005\u7684\u5173\u7cfb\uff0c\u8bf7\u81ea\u884c\u641c\u7d22\u6216\u5173\u6ce8\u516c\u4f17\u53f7\u540e\u7eed\u6587\u7ae0)\uff0c\u7136\u540e\u5c06sudog\u653e\u5165\u76d1\u542c\u7684\u94fe\u8868\u4e2d\u3002\u6267\u884c\u5230goparkunlock\u65f6\u5c31\u4f1a\u628a\u5f53\u524dgoroutine\u6539\u4e3a\u7b49\u5f85\u72b6\u6001\u5e76\u6302\u8d77\u3002\u6b64\u65f6\uff0c\u540e\u7eed\u4ee3\u7801\u5c06\u65e0\u6cd5\u6267\u884c\u3002<\/p>\n<h4 id=\"hsignal\">Signal<\/h4>\n<p>Signal\u65b9\u6cd5\u662f\u901a\u77e5\u5e76\u5524\u9192\u7ee7\u7eed\u6267\u884c\u4e00\u4e2agouroutine\u3002\u5176\u65b9\u6cd5\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\">1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-params\">(c\u00a0*Cond)<\/span>\u00a0<span class=\"hljs-title\">Signal<\/span><span class=\"hljs-params\">()<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">2<\/span>\u00a0\u00a0\u00a0\u00a0c.checker.check()\r\n<span class=\"linenum hljs-number\">3<\/span>\u00a0\u00a0\u00a0\u00a0runtime_notifyListNotifyOne(&amp;c.notify)\r\n<span class=\"linenum hljs-number\">4<\/span>}\r\n<\/code><\/pre>\n<p>\u800c\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u89c1runtime\/sema.go:<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\"> 1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-title\">notifyListNotifyOne<\/span><span class=\"hljs-params\">(l\u00a0*notifyList)<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\"> 2<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0Fast-path:\u00a0if\u00a0there\u00a0are\u00a0no\u00a0new\u00a0waiters\u00a0since\u00a0the\u00a0last\u00a0notification<\/span>\r\n<span class=\"linenum hljs-number\"> 3<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0we\u00a0don't\u00a0need\u00a0to\u00a0acquire\u00a0the\u00a0lock\u00a0at\u00a0all.<\/span>\r\n<span class=\"linenum hljs-number\"> 4<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0atomic.Load(&amp;l.wait)\u00a0==\u00a0atomic.Load(&amp;l.notify)\u00a0{\r\n<span class=\"linenum hljs-number\"> 5<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span>\r\n<span class=\"linenum hljs-number\"> 6<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\"> 7<\/span>\r\n<span class=\"linenum hljs-number\"> 8<\/span>\u00a0\u00a0\u00a0\u00a0lock(&amp;l.lock)\r\n<span class=\"linenum hljs-number\"> 9<\/span>\r\n<span class=\"linenum hljs-number\">10<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0Re-check\u00a0under\u00a0the\u00a0lock\u00a0if\u00a0we\u00a0need\u00a0to\u00a0do\u00a0anything.<\/span>\r\n<span class=\"linenum hljs-number\">11<\/span>\u00a0\u00a0\u00a0\u00a0t\u00a0:=\u00a0l.notify\r\n<span class=\"linenum hljs-number\">12<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0t\u00a0==\u00a0atomic.Load(&amp;l.wait)\u00a0{\r\n<span class=\"linenum hljs-number\">13<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unlock(&amp;l.lock)\r\n<span class=\"linenum hljs-number\">14<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span>\r\n<span class=\"linenum hljs-number\">15<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">16<\/span>\r\n<span class=\"linenum hljs-number\">17<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0Update\u00a0the\u00a0next\u00a0notify\u00a0ticket\u00a0number.<\/span>\r\n<span class=\"linenum hljs-number\">18<\/span>\u00a0\u00a0\u00a0\u00a0atomic.Store(&amp;l.notify,\u00a0t+<span class=\"hljs-number\">1<\/span>)\r\n<span class=\"linenum hljs-number\">19<\/span>\r\n<span class=\"linenum hljs-number\">20<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">for<\/span>\u00a0p,\u00a0s\u00a0:=\u00a0(*sudog)(<span class=\"hljs-literal\">nil<\/span>),\u00a0l.head;\u00a0s\u00a0!=\u00a0<span class=\"hljs-literal\">nil<\/span>;\u00a0p,\u00a0s\u00a0=\u00a0s,\u00a0s.next\u00a0{\r\n<span class=\"linenum hljs-number\">21<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0s.ticket\u00a0==\u00a0t\u00a0{\r\n<span class=\"linenum hljs-number\">22<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0n\u00a0:=\u00a0s.next\r\n<span class=\"linenum hljs-number\">23<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0p\u00a0!=\u00a0<span class=\"hljs-literal\">nil<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">24<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0p.next\u00a0=\u00a0n\r\n<span class=\"linenum hljs-number\">25<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\u00a0<span class=\"hljs-keyword\">else<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">26<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.head\u00a0=\u00a0n\r\n<span class=\"linenum hljs-number\">27<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">28<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0n\u00a0==\u00a0<span class=\"hljs-literal\">nil<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">29<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0l.tail\u00a0=\u00a0p\r\n<span class=\"linenum hljs-number\">30<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">31<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0unlock(&amp;l.lock)\r\n<span class=\"linenum hljs-number\">32<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0s.next\u00a0=\u00a0<span class=\"hljs-literal\">nil<\/span>\r\n<span class=\"linenum hljs-number\">33<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0readyWithTime(s,\u00a0<span class=\"hljs-number\">4<\/span>)\r\n<span class=\"linenum hljs-number\">34<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span>\r\n<span class=\"linenum hljs-number\">35<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">36<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">37<\/span>\u00a0\u00a0\u00a0\u00a0unlock(&amp;l.lock)\r\n<span class=\"linenum hljs-number\">38<\/span>}\r\n<\/code><\/pre>\n<p>\u9996\u5148\u662f\u4e00\u7cfb\u5217\u68c0\u67e5\uff0c\u5982\u679c\u4e0d\u7b26\u5408\u6761\u4ef6\uff0c\u5219\u76f4\u63a5\u9000\u51fa\u3002\u7136\u540e\u81ea\u589enotify\uff0c\u6807\u8bc6\u5df2\u7ecf\u901a\u77e5\u8fc7\u3002\u7136\u540e\u904d\u5386notifyList\u4e2d\u7684\u94fe\u8868\uff0c\u627e\u5230notify\u5bf9\u5e94\u7684sudog\uff0c\u7136\u540e\u8c03\u7528readWithTime\u51fd\u6570\uff0c\u5c06\u7761\u7720\u7684g\u518d\u5524\u9192\u7ee7\u7eed\u6267\u884c\u3002<\/p>\n<h4 id=\"hbroadcast\">Broadcast<\/h4>\n<p>Broadcast\u51fd\u6570\u548cSignal\u51fd\u6570\u6267\u884c\u8fc7\u7a0b\u51e0\u4e4e\u4e00\u81f4\uff0c\u53ea\u662f\u540e\u8005\u53ea\u5524\u9192\u94fe\u8868\u5934\u90e8\u7684\u4e00\u4e2ag\uff0c\u800cBroadcast\u5219\u662f\u5524\u9192\u6240\u6709\u5728Wait\u7684g\u3002<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\">1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-params\">(c\u00a0*Cond)<\/span>\u00a0<span class=\"hljs-title\">Broadcast<\/span><span class=\"hljs-params\">()<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">2<\/span>\u00a0\u00a0\u00a0\u00a0c.checker.check()\r\n<span class=\"linenum hljs-number\">3<\/span>\u00a0\u00a0\u00a0\u00a0runtime_notifyListNotifyAll(&amp;c.notify)\r\n<span class=\"linenum hljs-number\">4<\/span>}\r\n<\/code><\/pre>\n<p>\u5177\u4f53\u5b9e\u73b0\uff1a<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\"> 1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-title\">notifyListNotifyAll<\/span><span class=\"hljs-params\">(l\u00a0*notifyList)<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\"> 2<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0Fast-path:\u00a0if\u00a0there\u00a0are\u00a0no\u00a0new\u00a0waiters\u00a0since\u00a0the\u00a0last\u00a0notification<\/span>\r\n<span class=\"linenum hljs-number\"> 3<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0we\u00a0don't\u00a0need\u00a0to\u00a0acquire\u00a0the\u00a0lock.<\/span>\r\n<span class=\"linenum hljs-number\"> 4<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">if<\/span>\u00a0atomic.Load(&amp;l.wait)\u00a0==\u00a0atomic.Load(&amp;l.notify)\u00a0{\r\n<span class=\"linenum hljs-number\"> 5<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">return<\/span>\r\n<span class=\"linenum hljs-number\"> 6<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\"> 7<\/span>\r\n<span class=\"linenum hljs-number\"> 8<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0Pull\u00a0the\u00a0list\u00a0out\u00a0into\u00a0a\u00a0local\u00a0variable,\u00a0waiters\u00a0will\u00a0be\u00a0readied<\/span>\r\n<span class=\"linenum hljs-number\"> 9<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0outside\u00a0the\u00a0lock.<\/span>\r\n<span class=\"linenum hljs-number\">10<\/span>\u00a0\u00a0\u00a0\u00a0lock(&amp;l.lock)\r\n<span class=\"linenum hljs-number\">11<\/span>\u00a0\u00a0\u00a0\u00a0s\u00a0:=\u00a0l.head\r\n<span class=\"linenum hljs-number\">12<\/span>\u00a0\u00a0\u00a0\u00a0l.head\u00a0=\u00a0<span class=\"hljs-literal\">nil<\/span>\r\n<span class=\"linenum hljs-number\">13<\/span>\u00a0\u00a0\u00a0\u00a0l.tail\u00a0=\u00a0<span class=\"hljs-literal\">nil<\/span>\r\n<span class=\"linenum hljs-number\">14<\/span>\r\n<span class=\"linenum hljs-number\">15<\/span>\u00a0\u00a0\u00a0\u00a0atomic.Store(&amp;l.notify,\u00a0atomic.Load(&amp;l.wait))\r\n<span class=\"linenum hljs-number\">16<\/span>\u00a0\u00a0\u00a0\u00a0unlock(&amp;l.lock)\r\n<span class=\"linenum hljs-number\">17<\/span>\r\n<span class=\"linenum hljs-number\">18<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0Go\u00a0through\u00a0the\u00a0local\u00a0list\u00a0and\u00a0ready\u00a0all\u00a0waiters.<\/span>\r\n<span class=\"linenum hljs-number\">19<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">for<\/span>\u00a0s\u00a0!=\u00a0<span class=\"hljs-literal\">nil<\/span>\u00a0{\r\n<span class=\"linenum hljs-number\">20<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0next\u00a0:=\u00a0s.next\r\n<span class=\"linenum hljs-number\">21<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0s.next\u00a0=\u00a0<span class=\"hljs-literal\">nil<\/span>\r\n<span class=\"linenum hljs-number\">22<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0readyWithTime(s,\u00a0<span class=\"hljs-number\">4<\/span>)\r\n<span class=\"linenum hljs-number\">23<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0s\u00a0=\u00a0next\r\n<span class=\"linenum hljs-number\">24<\/span>\u00a0\u00a0\u00a0\u00a0}\r\n<span class=\"linenum hljs-number\">25<\/span>}\r\n<\/code><\/pre>\n<p>\u7740\u91cd\u6ce8\u610f\u4e00\u4e0b\u8fd9\u4e2a<code>atomic.Store(&amp;l.notify, atomic.Load(&amp;l.wait))<\/code>\uff0c\u5c31\u662f\u4e0d\u7ba1\u4f60\u6709\u591a\u5c11\u4e2ag\u5728\u7b49\u5f85\uff0c\u76f4\u63a5\u5c06notify\u8d4b\u503c\u4e3await\u3002\u7136\u540e\u904d\u5386\u6240\u6709\u6302\u8d77\u7684sudog\uff0c\u7136\u540e\u9010\u4e2a\u5524\u9192\u3002\u5176\u4ed6\u7684\u903b\u8f91\u548c\u4e0a\u9762\u5b8c\u5168\u4e00\u81f4\u3002<\/p>\n<p>sync.Cond\u7684\u6267\u884c\u903b\u8f91\u5df2\u7ecf\u5206\u6790\u5b8c\u4e86\uff0c\u4e0b\u9762\u8ba9\u6211\u4eec\u518d\u6765\u56de\u987e\u4e0a\u9762\u63d0\u51fa\u7684\u4e24\u4e2a\u95ee\u9898\u3002<\/p>\n<h4 id=\"h1signalgoroutine\">1. Signal()\u65b9\u6cd5\uff0c\u53d1\u51fa\u4fe1\u53f7\u540e\uff0c\u5524\u9192\u7684goroutine\u662f\u968f\u673a\u7684\u5417\uff1f<\/h4>\n<p>\u7ecf\u8fc7\u4e0a\u9762\u7684\u6e90\u7801\u5206\u6790\uff0c\u53ef\u4ee5\u5f97\u5230\u4e00\u4e2a\u5f88\u660e\u663e\u7684\u7b54\u6848\uff1a<strong>\u4e0d\u662f<\/strong>\u3002<\/p>\n<p>\u662f\u56e0\u4e3a\u5b58\u653enotifyList\u7684\u7ed3\u6784\u662f\u4e00\u4e2a\u94fe\u8868\u5417\uff1f\u5176\u5b9e\u4e5f\u4e0d\u662f\u3002\u56e0\u4e3a\u867d\u7136\u5b58\u653enotifyList\u7684\u7ed3\u6784\u662f\u4e00\u4e2a\u94fe\u8868\uff0c\u4f46\u662f\u5e76\u4e0d\u662f\u6309\u7167\u94fe\u8868\u4e2d\u7684\u987a\u5e8f\u76f4\u63a5\u904d\u5386\u83b7\u53d6\u7684\uff0c\u800c\u662f\u6839\u636ewait\u503c\u548csudog.ticket\u8fdb\u884c\u67e5\u627e\u5f97\u5230\u7684\u3002<\/p>\n<p>\u7136\u800c\uff0c\u67e5\u627e\u7684\u8fd9\u4e2await\u503c\u662f\u4e25\u683c\u9012\u589e\u7684\uff0c\u56e0\u6b64\u4e5f\u53ef\u4ee5\u8bf4\u662f\u5148\u8c03\u7528Wait()\u7684\u4f1a\u9996\u5148\u88ab\u5524\u9192\uff0c\u4e5f\u9075\u5faa\u5148\u8fdb\u5148\u51fa\u7684\u539f\u5219\u3002<\/p>\n<h4 id=\"h2synccondl\">2. sync.Cond\u4e2d\u7684L\u9501\u662f\u9501\u4ec0\u4e48\u7684\uff1f\u4e3a\u4ec0\u4e48\u8981\u6709\u8fd9\u4e2a\uff1f<\/h4>\n<p>\u5728\u4e0a\u8ff0\u6e90\u7801\u7684\u5206\u6790\u8fc7\u7a0b\u4e2d\uff0c\u9664\u4e86Wait()\u65b9\u6cd5\u4e2d\u7684c.L.Unlock\u548cc.L.Lock\u4ee5\u5916\uff0c\u6ca1\u6709\u5176\u4ed6\u5730\u65b9\u7528\u5230\uff0c\u90a3\u4e48\u5b83\u662f\u7528\u6765\u5e72\u561b\u7684\u5462\uff1f<\/p>\n<p>\u786e\u5b9e\uff0ccond.L\u5728\u4e0a\u8ff0\u8fc7\u7a0b\u4e2d\u662f\u6ca1\u6709\u7528\u5230\uff0c\u56e0\u6b64\u6b64\u5904\u5b58\u5728\u9501\u4e0d\u662f<strong>\u6280\u672f<\/strong>\u539f\u56e0\uff0c\u800c\u662f<strong>\u5de5\u7a0b<\/strong>\u65b9\u9762\u7684\u539f\u56e0\u3002\u8ba9\u6211\u4eec\u56de\u987e\u4e00\u4e0bsync.Cond\u7684\u4f7f\u7528\u573a\u666f\uff1a\u5f53\u67d0\u4e2a\u6761\u4ef6\u8fbe\u6210\u6216\u8005\u4efb\u52a1\u5b8c\u6210\u4e86\u4e4b\u540e\uff0c\u901a\u77e5\u5176\u4ed6\u7b49\u5f85\u7684goroutine\u3002\u5728\u8fd9\u79cd\u573a\u666f\u4e0b\uff0c\u5fc5\u7136\u5b58\u5728\u7740\u8d44\u6e90\u7ade\u4e89\uff0c\u90a3\u4e48\u5982\u4f55\u89e3\u51b3\u8d44\u6e90\u7ade\u4e89\u4e2d\u7684\u5e76\u53d1\u8bfb\u5199\u95ee\u9898\u5462\uff1f\u663e\u7136\u662f\u52a0\u9501\u3002\u4e0e\u5176\u5728\u5916\u9762\u8ba9\u4f7f\u7528\u8005\u81ea\u5df1\u52a0\u9501\uff0c\u4e0d\u5982\u5199\u5728\u5e93\u91cc\u9762\u5f3a\u5236\u8ba9\u4f7f\u7528\u8005\u8c03\u7528\u4ee5\u907f\u514d\u9057\u6f0f\u3002\u8fd9\u662f\u4e00\u79cd\u5de5\u7a0b\u65b9\u9762\u7684\u907f\u514d\u51fa\u95ee\u9898\u7684\u624b\u6bb5\u3002<\/p>\n<h3 id=\"h\">\u6ce8\u610f\u4e8b\u9879<\/h3>\n<p>\u4ee5\u4e0b\u6709\u51e0\u4e2a\u5728\u4f7f\u7528sync.Cond\u65f6\u7684\u6ce8\u610f\u4e8b\u9879\uff1a<\/p>\n<h5 id=\"hwaitcondllock\"><span style=\"font-size: 12pt;\">\u8c03\u7528Wait\u65b9\u6cd5\u4e4b\u524d\u5fc5\u987b\u8c03\u7528cond.L.Lock\u65b9\u6cd5\u3002<\/span><\/h5>\n<p>\u5728Wait\u65b9\u6cd5\u7684\u5b9e\u73b0\u4e2d\uff0c\u4f1a\u9996\u5148\u8c03\u7528Unlock\u65b9\u6cd5\uff0c\u5982\u679c\u4e4b\u524d\u6ca1\u6709\u8c03\u7528Lock\u65b9\u6cd5\uff0c\u4f1a\u9020\u6210panic\u3002<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\"> 1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\"> 2<\/span>\r\n<span class=\"linenum hljs-number\"> 3<\/span>\u00a0\u00a0\u00a0\u00a0locker\u00a0:=\u00a0sync.Mutex{}\r\n<span class=\"linenum hljs-number\"> 4<\/span>\u00a0\u00a0\u00a0\u00a0cond\u00a0:=\u00a0sync.NewCond(&amp;locker)\r\n<span class=\"linenum hljs-number\"> 5<\/span>\r\n<span class=\"linenum hljs-number\"> 6<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">go<\/span>\u00a0<span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span><span class=\"hljs-params\">()<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\"> 7<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cond.L.Lock()\r\n<span class=\"linenum hljs-number\"> 8<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cond.Signal()\r\n<span class=\"linenum hljs-number\"> 9<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cond.L.Unlock()\r\n<span class=\"linenum hljs-number\">10<\/span>\u00a0\u00a0\u00a0\u00a0}()\r\n<span class=\"linenum hljs-number\">11<\/span>\r\n<span class=\"linenum hljs-number\">12<\/span>\u00a0\u00a0\u00a0\u00a0cond.Wait()\r\n<span class=\"linenum hljs-number\">13<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0\u00a0fatal\u00a0error:\u00a0sync:\u00a0unlock\u00a0of\u00a0unlocked\u00a0mutex<\/span>\r\n<span class=\"linenum hljs-number\">14<\/span>}\r\n<\/code><\/pre>\n<h5 id=\"hwaitsignalbroadcast\"><span style=\"font-size: 12pt;\">Wait\u65b9\u6cd5\u5fc5\u987b\u5728Signal\u6216Broadcast\u65b9\u6cd5\u4e4b\u524d\u8c03\u7528\uff0c\u5426\u5219\u53ef\u80fd\u4f1a\u9020\u6210\u6b7b\u9501\u3002<\/span><\/h5>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\"> 1<\/span><span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span>\u00a0<span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\"> 2<\/span>\r\n<span class=\"linenum hljs-number\"> 3<\/span>\u00a0\u00a0\u00a0\u00a0locker\u00a0:=\u00a0sync.Mutex{}\r\n<span class=\"linenum hljs-number\"> 4<\/span>\u00a0\u00a0\u00a0\u00a0cond\u00a0:=\u00a0sync.NewCond(&amp;locker)\r\n<span class=\"linenum hljs-number\"> 5<\/span>\r\n<span class=\"linenum hljs-number\"> 6<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-keyword\">go<\/span>\u00a0<span class=\"hljs-function\"><span class=\"hljs-keyword\">func<\/span><span class=\"hljs-params\">()<\/span><\/span>\u00a0{\r\n<span class=\"linenum hljs-number\"> 7<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cond.L.Lock()\r\n<span class=\"linenum hljs-number\"> 8<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cond.Signal()\r\n<span class=\"linenum hljs-number\"> 9<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cond.L.Unlock()\r\n<span class=\"linenum hljs-number\">10<\/span>\u00a0\u00a0\u00a0\u00a0}()\r\n<span class=\"linenum hljs-number\">11<\/span>\r\n<span class=\"linenum hljs-number\">12<\/span>\u00a0\u00a0\u00a0\u00a0time.Sleep(time.Second)\r\n<span class=\"linenum hljs-number\">13<\/span>\u00a0\u00a0\u00a0\u00a0cond.L.Lock()\r\n<span class=\"linenum hljs-number\">14<\/span>\u00a0\u00a0\u00a0\u00a0cond.Wait()\r\n<span class=\"linenum hljs-number\">15<\/span>\u00a0\u00a0\u00a0\u00a0cond.L.Unlock()\r\n<span class=\"linenum hljs-number\">16<\/span>\u00a0\u00a0\u00a0\u00a0<span class=\"hljs-comment\">\/\/\u00a0fatal\u00a0error:\u00a0all\u00a0goroutines\u00a0are\u00a0asleep\u00a0-\u00a0deadlock!<\/span>\r\n<span class=\"linenum hljs-number\">17<\/span>}\r\n<\/code><\/pre>\n<h6 id=\"hcondwait\"><span style=\"font-size: 12pt;\">cond.Wait\u5e94\u8be5\u5728\u4e00\u4e2a\u5faa\u73af\u4e2d\u8c03\u7528<\/span><\/h6>\n<p>\u56e0\u4e3a\u8c03\u7528\u9996\u6b21\u8c03\u7528cond.Wait\u540e\uff0ccond.L\u4f1a\u5728Wait\u65b9\u6cd5\u4e2d\u88abUnlock\u4ece\u800c\u5931\u53bb\u9501\uff0c\u65e0\u6cd5\u786e\u5b9a\u8d44\u6e90\u72b6\u6001\u662f\u5426\u88ab\u6539\u53d8\u4e86\uff0c\u56e0\u6b64\u5728Wait\u51fd\u6570\u8fd4\u56de\u65f6\u65e0\u6cd5\u786e\u5b9a\u6761\u4ef6\u662f\u5426\u8fbe\u6210\uff0c\u6240\u4ee5\u9700\u8981\u5728\u4e00\u4e2a\u5faa\u73af\u4e2d\u8c03\u7528cond.Wait\uff0c\u5f53\u8c03\u7528\u7ed3\u675f\u540e\u518d\u6b21\u5224\u65ad\u6761\u4ef6\u662f\u5426\u8fbe\u6210\uff0c\u5982\u679c\u6761\u4ef6\u672a\u8fbe\u6210\uff0c\u5219\u5faa\u73af\u4e00\u76f4\u6267\u884c\u3002\u63a8\u8350\u5199\u6cd5\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"go language-go hljs\"><span class=\"linenum hljs-number\">1<\/span>c.L.Lock()\r\n<span class=\"linenum hljs-number\">2<\/span><span class=\"hljs-keyword\">for<\/span>\u00a0!condition()\u00a0{\r\n<span class=\"linenum hljs-number\">3<\/span>\u00a0\u00a0\u00a0c.Wait()\r\n<span class=\"linenum hljs-number\">4<\/span>}\r\n<span class=\"linenum hljs-number\">5<\/span><span class=\"hljs-comment\">\/\/...\u00a0make\u00a0use\u00a0of\u00a0condition\u00a0...<\/span>\r\n<span class=\"linenum hljs-number\">6<\/span>c.L.Unlock()\r\n<\/code><\/pre>\n<\/section>\n<\/section>\n","protected":false},"excerpt":{"rendered":"<p>\u6700\u8fd1\u9047\u5230\u4e00\u4e2a\u8fd9\u6837\u7684\u573a\u666f\uff1a\u5f53\u67d0\u4e2a\u6761\u4ef6\u6216\u8005\u4efb\u52a1\u5b8c\u6210\u4e86\u4e4b\u540e\uff0c\u901a\u77e5\u5176\u4ed6\u7b49\u5f85\u7684\u5404\u4e2a\u201c\u5b88\u62a4goroutine\u201d\uff08\u5373\u6b7b\u5faa\u73af\u6267\u884c\u67d0\u9879\u4efb\u52a1\u7684goroutine\uff09\u7ee7\u7eed\u6267\u884c\u3002\u9996\u5148\u60f3\u5230\u7684\u662f\u4f7f\u7528channel\u6765\u5b8c\u6210\uff0c\u7136\u800cchannel\u6709\u4e00\u5b9a\u7684\u5c40\u9650\u6027\u3002\u9996\u5148\uff0cchannel\u6bd4\u8f83\u9002\u7528\u4e8e\u4e00\u5bf9\u4e00\uff0c\u5f3a\u884c\u4e00\u5bf9\u591a\u7684\u8bdd\u6bd4\u8f83\u96be\u53d7\uff0c\u4e0d\u8fc7\u4e5f\u53ef\u4ee5\u4f7f\u7528close\u5173\u95edchannel\u6765\u8fbe\u5230\u901a\u77e5\u6240\u2026\u2026<\/p>\n","protected":false},"author":1,"featured_media":4,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/chenqinghe.com\/index.php?rest_route=\/wp\/v2\/posts\/60"}],"collection":[{"href":"https:\/\/chenqinghe.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chenqinghe.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chenqinghe.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chenqinghe.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=60"}],"version-history":[{"count":0,"href":"https:\/\/chenqinghe.com\/index.php?rest_route=\/wp\/v2\/posts\/60\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chenqinghe.com\/index.php?rest_route=\/wp\/v2\/media\/4"}],"wp:attachment":[{"href":"https:\/\/chenqinghe.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=60"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chenqinghe.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=60"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chenqinghe.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=60"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}