{"id":4072,"date":"2020-01-20T15:32:15","date_gmt":"2020-01-20T07:32:15","guid":{"rendered":"https:\/\/damogame.cn\/wordpress\/?p=4072"},"modified":"2020-01-20T15:32:15","modified_gmt":"2020-01-20T07:32:15","slug":"sync-waitgroup%e7%9a%84%e4%bd%bf%e7%94%a8%e4%bb%a5%e5%8f%8a%e5%9d%91","status":"publish","type":"post","link":"https:\/\/i007.cc\/wordpress\/archives\/4072","title":{"rendered":"sync.WaitGroup\u7684\u4f7f\u7528\u4ee5\u53ca\u5751"},"content":{"rendered":"<div class=\"rEsl9f\">\n<div class=\"_2mYfmT\">\n<div>\n<div class=\"s-dsoj\"><a href=\"https:\/\/www.jianshu.com\/p\/4c2c80076094\">\u539f\u6587\u5730\u5740<\/a><\/div>\n<div><\/div>\n<\/div>\n<\/div>\n<\/div>\n<article class=\"_2rhmJa\">\u7b80\u5355\u4f7f\u7528\uff1a<\/p>\n<div class=\"_2Uzcx_\"><button class=\"VJbwyy\" type=\"button\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><i class=\"anticon anticon-copy\" aria-label=\"icon: copy\"><\/i><\/button><\/p>\n<pre class=\"line-numbers  language-go\"><code class=\"  language-go\"><span class=\"token keyword\">package<\/span> main\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token string\">\"sync\"<\/span>\r\n<span class=\"token punctuation\">)<\/span>\r\n\r\n<span class=\"token keyword\">type<\/span> httpPkg <span class=\"token keyword\">struct<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">func<\/span> <span class=\"token punctuation\">(<\/span>httpPkg<span class=\"token punctuation\">)<\/span> <span class=\"token function\">Get<\/span><span class=\"token punctuation\">(<\/span>url <span class=\"token builtin\">string<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">var<\/span> http httpPkg\r\n\r\n<span class=\"token keyword\">func<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">var<\/span> wg sync<span class=\"token punctuation\">.<\/span>WaitGroup\r\n    <span class=\"token keyword\">var<\/span> urls <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token builtin\">string<\/span><span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token string\">\"http:\/\/www.golang.org\/\"<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">\"http:\/\/www.google.com\/\"<\/span><span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token string\">\"http:\/\/www.somestupidname.com\/\"<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token punctuation\">}<\/span>\r\n    <span class=\"token keyword\">for<\/span> <span class=\"token boolean\">_<\/span><span class=\"token punctuation\">,<\/span> url <span class=\"token operator\">:=<\/span> <span class=\"token keyword\">range<\/span> urls <span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token comment\">\/\/ Increment the WaitGroup counter.<\/span>\r\n        wg<span class=\"token punctuation\">.<\/span><span class=\"token function\">Add<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span>\r\n        <span class=\"token comment\">\/\/ Launch a goroutine to fetch the URL.<\/span>\r\n        <span class=\"token keyword\">go<\/span> <span class=\"token keyword\">func<\/span><span class=\"token punctuation\">(<\/span>url <span class=\"token builtin\">string<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n            <span class=\"token comment\">\/\/ Decrement the counter when the goroutine completes.<\/span>\r\n            <span class=\"token keyword\">defer<\/span> wg<span class=\"token punctuation\">.<\/span><span class=\"token function\">Done<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>\r\n            <span class=\"token comment\">\/\/ Fetch the URL.<\/span>\r\n            http<span class=\"token punctuation\">.<\/span><span class=\"token function\">Get<\/span><span class=\"token punctuation\">(<\/span>url<span class=\"token punctuation\">)<\/span>\r\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">(<\/span>url<span class=\"token punctuation\">)<\/span>\r\n    <span class=\"token punctuation\">}<\/span>\r\n    <span class=\"token comment\">\/\/ Wait for all HTTP fetches to complete.<\/span>\r\n    wg<span class=\"token punctuation\">.<\/span><span class=\"token function\">Wait<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/golang.org\/pkg\/sync\/#example_WaitGroup\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\u8fd9\u662fgolang\u5b98\u7f51\u4e0a\u7684\u4f8b\u5b50<\/a><\/p>\n<p>\u8ddfjava\u7684<code>CountdownLatch<\/code>\u5dee\u4e0d\u591a\uff0c\u4e5f\u662f\u963b\u585e\u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\u4e4b\u540e\u518d\u7ee7\u7eed\u6267\u884c\u3002<\/p>\n<p>\u7b80\u5355\u4f7f\u7528\u5c31\u662f\u5728\u521b\u5efa\u4e00\u4e2a\u4efb\u52a1\u7684\u65f6\u5019<code>wg.Add(1)<\/code>, \u4efb\u52a1\u5b8c\u6210\u7684\u65f6\u5019\u4f7f\u7528<code>wg.Done()<\/code>\u6765\u5c06\u4efb\u52a1\u51cf\u4e00\u3002\u4f7f\u7528<code>wg.Wait()<\/code>\u6765\u963b\u585e\u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\u3002<\/p>\n<p>\u7136\u540e\u6211\u5c31\u5199\u4e86\u4e00\u4e2a\u4f8b\u5b50\uff1a<\/p>\n<div class=\"_2Uzcx_\"><button class=\"VJbwyy\" type=\"button\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><i class=\"anticon anticon-copy\" aria-label=\"icon: copy\"><\/i><\/button><\/p>\n<pre class=\"line-numbers  language-golang\"><code class=\"golang  language-golang\">func main() {\r\n    var wg sync.WaitGroup\r\n    ch := make(chan int, 1000)\r\n    for i := 0; i &lt; 1000; i++ {\r\n        wg.Add(1)\r\n        go doSomething(i, wg, ch)\r\n    }\r\n    wg.Wait()\r\n    fmt.Println(\"all done\")\r\n    for i := 0; i &lt; 1000; i++ {\r\n        dd := &lt;-ch\r\n        fmt.Println(\"from ch:\"+strconv.Itoa(dd))\r\n    }\r\n}\r\n\r\nfunc doSomething(index int, wg  sync.WaitGroup, ch chan int) {\r\n    defer wg.Done()\r\n    fmt.Println(\"start done:\" + strconv.Itoa(index))\r\n    \/\/time.Sleep(20 * time.Millisecond)\r\n    ch &lt;- index\r\n}\r\n<\/code><\/pre>\n<\/div>\n<p>\u7136\u540e\u5c31\u62a5\u9519\u4e86\uff1a<\/p>\n<div class=\"_2Uzcx_\"><button class=\"VJbwyy\" type=\"button\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><i class=\"anticon anticon-copy\" aria-label=\"icon: copy\"><\/i><\/button><\/p>\n<pre class=\"line-numbers  language-golang\"><code class=\"golang  language-golang\">fatal error: all goroutines are asleep - deadlock!\r\ngoroutine 1 [semacquire]:\r\nsync.runtime_Semacquire(0xc42001608c)\r\n    \/usr\/local\/Cellar\/go\/1.10.3\/libexec\/src\/runtime\/sema.go:56 +0x39\r\nsync.(*WaitGroup).Wait(0xc420016080)\r\n    \/usr\/local\/Cellar\/go\/1.10.3\/libexec\/src\/sync\/waitgroup.go:129 +0x72\r\nmain.main()\r\n    \/Users\/taoli\/go\/src\/github.com\/c60\/cai\/tx_gorutine.go:16 +0xea\r\n<\/code><\/pre>\n<\/div>\n<p>\u600e\u4e48\u56de\u4e8b\uff0c\u4ed6\u8bf4\u6b7b\u9501\u4e86\u3002<br \/>\n\u539f\u6765\u8fd9\u662f\u8bf4\uff0c\u6240\u6709\u7684\u534f\u7a0b\u90fd\u8fd0\u884c\u5b8c\u4e86\uff0c\u4f60\u8fd9\u8fb9\u8fd8\u5728\u7b49\u5f85\u3002<\/p>\n<p>\u4ec0\u4e48\u539f\u56e0\u5bfc\u81f4\u7684\u5462\uff1f<br \/>\n\u539f\u6765\u662fgolang\u91cc\u5982\u679c\u65b9\u6cd5\u4f20\u9012\u7684\u4e0d\u662f\u5730\u5740\uff0c\u90a3\u4e48\u5c31\u4f1a\u505a\u4e00\u4e2a\u62f7\u8d1d\uff0c\u6240\u4ee5\u8fd9\u91cc\u8c03\u7528\u7684wg\u6839\u672c\u5c31\u4e0d\u662f\u4e00\u4e2a\u5bf9\u8c61\u3002<\/p>\n<p>\u4f20\u9012\u7684\u5730\u65b9\u4f20\u9012\u5730\u5740\u5c31\u53ef\u4ee5\u4e86\uff1a<\/p>\n<div class=\"_2Uzcx_\"><button class=\"VJbwyy\" type=\"button\" aria-label=\"\u590d\u5236\u4ee3\u7801\"><i class=\"anticon anticon-copy\" aria-label=\"icon: copy\"><\/i><\/button><\/p>\n<pre class=\"line-numbers  language-go\"><code class=\"  language-go\"><span class=\"token keyword\">go<\/span> <span class=\"token function\">doSomething<\/span><span class=\"token punctuation\">(<\/span>i<span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&amp;<\/span>wg<span class=\"token punctuation\">,<\/span> ch<span class=\"token punctuation\">)<\/span>\r\n\r\n<span class=\"token keyword\">func<\/span> <span class=\"token function\">doSomething<\/span><span class=\"token punctuation\">(<\/span>index <span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> wg <span class=\"token operator\">*<\/span>sync<span class=\"token punctuation\">.<\/span>WaitGroup<span class=\"token punctuation\">,<\/span> ch <span class=\"token keyword\">chan<\/span> <span class=\"token builtin\">int<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/code><\/pre>\n<\/div>\n<\/article>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u6587\u5730\u5740 \u7b80\u5355\u4f7f\u7528\uff1a package m<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[],"tags":[122],"class_list":["post-4072","post","type-post","status-publish","format-standard","hentry","tag-06-godocker"],"_links":{"self":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/4072","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/comments?post=4072"}],"version-history":[{"count":0,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/posts\/4072\/revisions"}],"wp:attachment":[{"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/media?parent=4072"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/categories?post=4072"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/i007.cc\/wordpress\/wp-json\/wp\/v2\/tags?post=4072"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}