[{"data":1,"prerenderedAt":1274},["ShallowReactive",2],{"content:\u002F2025\u002F08\u002Fgo-context1":3,"surround:\u002F2025\u002F08\u002Fgo-context1":1263},{"id":4,"title":5,"body":6,"categories":1242,"date":1244,"description":1245,"draft":1246,"extension":1247,"image":1248,"meta":1249,"navigation":259,"path":1251,"permalink":1248,"published":1248,"readingTime":1252,"recommend":1248,"references":1248,"seo":1257,"sitemap":1258,"stem":1259,"tags":1260,"type":1261,"updated":1244,"__hash__":1262},"content\u002Fposts\u002F2025\u002F08\u002Fgo-context1.md","Go Context 原理与使用实践",{"type":7,"value":8,"toc":1236},"minimark",[9,14,177,185,201,205,208,211,214,374,377,385,388,392,544,558,566,568,1207,1210,1216,1220,1223,1232],[10,11,13],"h2",{"id":12},"context-数据结构","context 数据结构",[15,16,21],"pre",{"className":17,"code":18,"language":19,"meta":20,"style":20},"language-go shiki shiki-themes github-light github-dark","type Context interface {\n\tDeadline() (deadline time.Time, ok bool)\n\tDone() \u003C-chan struct{}\n\tErr() error\n\tValue(key interface{}) interface{}\n}\n","go","",[22,23,24,48,94,123,140,172],"code",{"__ignoreMap":20},[25,26,29,33,37,40,44],"span",{"class":27,"data-line":28,"line":28},"line",1,[25,30,32],{"class":31},"szBVR","type",[25,34,36],{"class":35},"sScJk"," Context",[25,38,39],{"class":31}," interface",[25,41,43],{"class":42},"sVt8B"," ",[25,45,47],{"class":46},"sSDpw","{\n",[25,49,51,55,58,62,65,67,69,73,76,79,82,85,88,91],{"class":27,"data-line":50,"line":50},2,[25,52,54],{"class":53},"indent","\t",[25,56,57],{"class":35},"Deadline",[25,59,61],{"class":60},"sJX2D","(",[25,63,64],{"class":60},")",[25,66,43],{"class":42},[25,68,61],{"class":60},[25,70,72],{"class":71},"s4XuR","deadline",[25,74,75],{"class":35}," time",[25,77,78],{"class":42},".",[25,80,81],{"class":35},"Time",[25,83,84],{"class":42},", ",[25,86,87],{"class":71},"ok",[25,89,90],{"class":31}," bool",[25,92,93],{"class":60},")\n",[25,95,97,99,102,104,106,108,111,114,117,120],{"class":27,"data-line":96,"line":96},3,[25,98,54],{"class":53},[25,100,101],{"class":35},"Done",[25,103,61],{"class":60},[25,105,64],{"class":60},[25,107,43],{"class":42},[25,109,110],{"class":31},"\u003C",[25,112,113],{"class":31},"-chan",[25,115,116],{"class":31}," struct",[25,118,119],{"class":60},"{",[25,121,122],{"class":60},"}\n",[25,124,126,128,131,133,135,137],{"class":27,"data-line":125,"line":125},4,[25,127,54],{"class":53},[25,129,130],{"class":35},"Err",[25,132,61],{"class":60},[25,134,64],{"class":60},[25,136,43],{"class":42},[25,138,139],{"class":31},"error\n",[25,141,143,145,148,150,153,155,158,161,163,165,168,170],{"class":27,"data-line":142,"line":142},5,[25,144,54],{"class":53},[25,146,147],{"class":35},"Value",[25,149,61],{"class":60},[25,151,152],{"class":71},"key",[25,154,39],{"class":31},[25,156,119],{"class":157},"sqkie",[25,159,160],{"class":157},"}",[25,162,64],{"class":60},[25,164,43],{"class":42},[25,166,167],{"class":31},"interface",[25,169,119],{"class":60},[25,171,122],{"class":60},[25,173,175],{"class":27,"data-line":174,"line":174},6,[25,176,122],{"class":46},[178,179,180,181,184],"p",{},"这是 go 官方的 context 包，其中的",[22,182,183],{"code":183},"Context","数据结构实现了以下四个方法",[186,187,188,192,195,198],"ul",{},[189,190,191],"li",{},"Deadline：获取 context 的截止时间，ok 表示是否设置了超时时间。",[189,193,194],{},"Done：当 context 被取消或达到截止时间时，返回的只读 channel 会被关闭，用来传递取消信号。",[189,196,197],{},"Err：在 Done 关闭后返回错误信息（context.Canceled 或 context.DeadlineExceeded），在此之前返回 nil。",[189,199,200],{},"Value：获取 context 中存储的值（通常用来传递请求范围内的元数据，如 traceID、用户信息）。",[10,202,204],{"id":203},"创建-context","创建 context",[178,206,207],{},"context.Background() -- 根 context\ncontext.TODO() -- 占位，类型和 Background 一致但是未确定是使用根 context 还是传递的 context",[178,209,210],{},"这两个都是根 context，然后均为无超时，无取消，无值的“三无”根 context",[178,212,213],{},"来看一段代码",[15,215,217],{"className":17,"code":216,"language":19,"meta":20,"style":20},"func TestDeadline() {\n\tctx := context.Background()\n\n\tdeadTime, ok := ctx.Deadline()\n\tfmt.Println(\"超时时间和是否设置超时\", deadTime, ok)\n\n\n\t\u002F\u002F 死锁, 因为context.Background()是无超时\n\t\u002F\u002F \u003C-ctx.Done()\n\n\tfmt.Printf(\"ctx.Err(): %v\\n\", ctx.Err())\n\n}\n",[22,218,219,235,255,261,279,300,304,309,318,326,331,364,369],{"__ignoreMap":20},[25,220,221,224,227,229,231,233],{"class":27,"data-line":28,"line":28},[25,222,223],{"class":31},"func",[25,225,226],{"class":35}," TestDeadline",[25,228,61],{"class":46},[25,230,64],{"class":46},[25,232,43],{"class":42},[25,234,47],{"class":46},[25,236,237,239,242,245,248,251,253],{"class":27,"data-line":50,"line":50},[25,238,54],{"class":53},[25,240,241],{"class":42},"ctx ",[25,243,244],{"class":31},":=",[25,246,247],{"class":42}," context.",[25,249,250],{"class":35},"Background",[25,252,61],{"class":60},[25,254,93],{"class":60},[25,256,257],{"class":27,"data-line":96,"line":96},[25,258,260],{"emptyLinePlaceholder":259},true,"\n",[25,262,263,265,268,270,273,275,277],{"class":27,"data-line":125,"line":125},[25,264,54],{"class":53},[25,266,267],{"class":42},"deadTime, ok ",[25,269,244],{"class":31},[25,271,272],{"class":42}," ctx.",[25,274,57],{"class":35},[25,276,61],{"class":60},[25,278,93],{"class":60},[25,280,281,283,286,289,291,295,298],{"class":27,"data-line":142,"line":142},[25,282,54],{"class":53},[25,284,285],{"class":42},"fmt.",[25,287,288],{"class":35},"Println",[25,290,61],{"class":60},[25,292,294],{"class":293},"sZZnC","\"超时时间和是否设置超时\"",[25,296,297],{"class":42},", deadTime, ok",[25,299,93],{"class":60},[25,301,302],{"class":27,"data-line":174,"line":174},[25,303,260],{"emptyLinePlaceholder":259},[25,305,307],{"class":27,"data-line":306,"line":306},7,[25,308,260],{"emptyLinePlaceholder":259},[25,310,312,314],{"class":27,"data-line":311,"line":311},8,[25,313,54],{"class":53},[25,315,317],{"class":316},"sJ8bj","\u002F\u002F 死锁, 因为context.Background()是无超时\n",[25,319,321,323],{"class":27,"data-line":320,"line":320},9,[25,322,54],{"class":53},[25,324,325],{"class":316},"\u002F\u002F \u003C-ctx.Done()\n",[25,327,329],{"class":27,"data-line":328,"line":328},10,[25,330,260],{"emptyLinePlaceholder":259},[25,332,334,336,338,341,343,346,350,353,356,358,360,362],{"class":27,"data-line":333,"line":333},11,[25,335,54],{"class":53},[25,337,285],{"class":42},[25,339,340],{"class":35},"Printf",[25,342,61],{"class":60},[25,344,345],{"class":293},"\"ctx.Err(): ",[25,347,349],{"class":348},"sj4cs","%v\\n",[25,351,352],{"class":293},"\"",[25,354,355],{"class":42},", ctx.",[25,357,130],{"class":35},[25,359,61],{"class":157},[25,361,64],{"class":157},[25,363,93],{"class":60},[25,365,367],{"class":27,"data-line":366,"line":366},12,[25,368,260],{"emptyLinePlaceholder":259},[25,370,372],{"class":27,"data-line":371,"line":371},13,[25,373,122],{"class":46},[178,375,376],{},"输出结果",[15,378,383],{"className":379,"code":381,"language":382,"meta":20},[380],"language-text","超时时间和是否设置超时 0001-01-01 00:00:00 +0000 UTC false\nctx.Err(): \u003Cnil>\n","text",[22,384,381],{"__ignoreMap":20},[178,386,387],{},"注释的部分是因为根 context 无超时时间，所以 channel 永久不会，发送超时信号【channel 在退出的时候，为空继续拿值会拿其零值】，一直阻塞造成死锁",[10,389,391],{"id":390},"context-的派生","context 的派生",[15,393,395],{"className":17,"code":394,"language":19,"meta":20,"style":20},"func WithCancel(parent Context) (ctx Context, cancel CancelFunc)\nfunc WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)\nfunc WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)\nfunc WithValue(parent Context, key, val interface{}) Context\n",[22,396,397,432,470,509],{"__ignoreMap":20},[25,398,399,401,404,406,409,411,413,415,417,420,422,424,427,430],{"class":27,"data-line":28,"line":28},[25,400,223],{"class":31},[25,402,403],{"class":35}," WithCancel",[25,405,61],{"class":46},[25,407,408],{"class":71},"parent",[25,410,36],{"class":35},[25,412,64],{"class":46},[25,414,43],{"class":42},[25,416,61],{"class":46},[25,418,419],{"class":71},"ctx",[25,421,36],{"class":35},[25,423,84],{"class":42},[25,425,426],{"class":71},"cancel",[25,428,429],{"class":35}," CancelFunc",[25,431,93],{"class":46},[25,433,434,436,439,441,443,445,447,449,451,453,455,457,459,461,463,465,468],{"class":27,"data-line":50,"line":50},[25,435,223],{"class":31},[25,437,438],{"class":35}," WithDeadline",[25,440,61],{"class":46},[25,442,408],{"class":71},[25,444,36],{"class":35},[25,446,84],{"class":42},[25,448,72],{"class":71},[25,450,75],{"class":35},[25,452,78],{"class":42},[25,454,81],{"class":35},[25,456,64],{"class":46},[25,458,43],{"class":42},[25,460,61],{"class":46},[25,462,183],{"class":35},[25,464,84],{"class":42},[25,466,467],{"class":35},"CancelFunc",[25,469,93],{"class":46},[25,471,472,474,477,479,481,483,485,488,490,492,495,497,499,501,503,505,507],{"class":27,"data-line":96,"line":96},[25,473,223],{"class":31},[25,475,476],{"class":35}," WithTimeout",[25,478,61],{"class":46},[25,480,408],{"class":71},[25,482,36],{"class":35},[25,484,84],{"class":42},[25,486,487],{"class":71},"timeout",[25,489,75],{"class":35},[25,491,78],{"class":42},[25,493,494],{"class":35},"Duration",[25,496,64],{"class":46},[25,498,43],{"class":42},[25,500,61],{"class":46},[25,502,183],{"class":35},[25,504,84],{"class":42},[25,506,467],{"class":35},[25,508,93],{"class":46},[25,510,511,513,516,518,520,522,524,526,528,531,533,535,537,539,541],{"class":27,"data-line":125,"line":125},[25,512,223],{"class":31},[25,514,515],{"class":35}," WithValue",[25,517,61],{"class":46},[25,519,408],{"class":71},[25,521,36],{"class":35},[25,523,84],{"class":42},[25,525,152],{"class":71},[25,527,84],{"class":42},[25,529,530],{"class":71},"val",[25,532,39],{"class":31},[25,534,119],{"class":60},[25,536,160],{"class":60},[25,538,64],{"class":46},[25,540,43],{"class":42},[25,542,543],{"class":35},"Context\n",[186,545,546,549,552,555],{},[189,547,548],{},"WithCancel，可用于创建子 context，附带撤销机制",[189,550,551],{},"WithDeadline，可用于创建子 context，附带撤销机制，同时附带超时控制",[189,553,554],{},"WithTimeout，类似 WithDeadline，但是传递的 duration，方便些",[189,556,557],{},"WithValue，父 context 的派生，设置值",[178,559,560,565],{},[561,562],"img",{"alt":563,"src":564},"context","https:\u002F\u002Fcdn.jsdelivr.net\u002Fgh\u002Fcodepzj\u002Fimages@main\u002F20250820162659687.png","\n通过根 context，通过四个 with 系列方法可以派生出四种类型的 context，每种 context 又可以通过同样的方式调用 with 系列方法继续向下派生新的 context，整个结构像一棵树。",[178,567,213],{},[15,569,571],{"className":17,"code":570,"language":19,"meta":20,"style":20},"func func1(ctx context.Context, name string) {\n\tselect {\n\tcase \u003C-ctx.Done():\n\t\tfmt.Printf(\"%s, 超时了, 准备退出...\\n\", name)\n\t\tfmt.Println(\"ctx.Err\", ctx.Err().Error())\n\tcase \u003C-time.After(3 * time.Second):\n\t\tfmt.Printf(\"%s, 数据库查询完成\\n\", name)\n\t}\n}\n\nfunc func2(ctx context.Context) {\n\tfmt.Printf(\"ctx.Value(\\\"name\\\").(string): %v\\n\", ctx.Value(\"name\").(string))\n}\n\nfunc main() {\n\t\u002F* ---------- context派生 ---------- *\u002F\n\tctx1, cancel := context.WithCancel(parent)\n\tgo func1(ctx1, \"cancel\")\n\ttime.Sleep(2 * time.Second)\n\tcancel() \u002F\u002F 子goroutine 2s之后超时退出\n\n\tctx2, cancel2 := context.WithDeadline(parent, time.Now().Add(1*time.Second))\n\tgo func1(ctx2, \"deadline\") \u002F\u002F 子goroutine 1s之后超时退出\n\tdefer cancel2()\n\n\tctx3, cancel3 := context.WithTimeout(parent, 500*time.Millisecond)\n\tgo func1(ctx3, \"timeout\") \u002F\u002F 子goroutine 0.5s之后超时退出\n\tdefer cancel3()\n\n\tctx4 := context.WithValue(parent, \"name\", \"codepzj\")\n\tgo func2(ctx4)\n\n\ttime.Sleep(5 * time.Second)\n}\n",[22,572,573,605,616,642,672,706,739,766,774,778,782,805,854,858,863,879,887,908,927,948,964,969,1016,1040,1055,1060,1090,1114,1128,1133,1161,1177,1182,1202],{"__ignoreMap":20},[25,574,575,577,580,582,584,587,589,591,593,596,599,601,603],{"class":27,"data-line":28,"line":28},[25,576,223],{"class":31},[25,578,579],{"class":35}," func1",[25,581,61],{"class":46},[25,583,419],{"class":71},[25,585,586],{"class":35}," context",[25,588,78],{"class":42},[25,590,183],{"class":35},[25,592,84],{"class":42},[25,594,595],{"class":71},"name",[25,597,598],{"class":31}," string",[25,600,64],{"class":46},[25,602,43],{"class":42},[25,604,47],{"class":46},[25,606,607,609,612,614],{"class":27,"data-line":50,"line":50},[25,608,54],{"class":53},[25,610,611],{"class":31},"select",[25,613,43],{"class":42},[25,615,47],{"class":60},[25,617,618,620,623,625,627,630,633,635,637,639],{"class":27,"data-line":96,"line":96},[25,619,54],{"class":53},[25,621,622],{"class":31},"case",[25,624,43],{"class":31},[25,626,110],{"class":31},[25,628,629],{"class":31},"-",[25,631,632],{"class":42},"ctx.",[25,634,101],{"class":35},[25,636,61],{"class":157},[25,638,64],{"class":157},[25,640,641],{"class":42},":\n",[25,643,644,646,648,650,652,654,656,659,662,665,667,670],{"class":27,"data-line":125,"line":125},[25,645,54],{"class":53},[25,647,54],{"class":53},[25,649,285],{"class":42},[25,651,340],{"class":35},[25,653,61],{"class":157},[25,655,352],{"class":293},[25,657,658],{"class":348},"%s",[25,660,661],{"class":293},", 超时了, 准备退出...",[25,663,664],{"class":348},"\\n",[25,666,352],{"class":293},[25,668,669],{"class":42},", name",[25,671,93],{"class":157},[25,673,674,676,678,680,682,684,687,689,691,693,695,697,700,702,704],{"class":27,"data-line":142,"line":142},[25,675,54],{"class":53},[25,677,54],{"class":53},[25,679,285],{"class":42},[25,681,288],{"class":35},[25,683,61],{"class":157},[25,685,686],{"class":293},"\"ctx.Err\"",[25,688,355],{"class":42},[25,690,130],{"class":35},[25,692,61],{"class":46},[25,694,64],{"class":46},[25,696,78],{"class":42},[25,698,699],{"class":35},"Error",[25,701,61],{"class":46},[25,703,64],{"class":46},[25,705,93],{"class":157},[25,707,708,710,712,714,716,718,721,724,726,729,732,735,737],{"class":27,"data-line":174,"line":174},[25,709,54],{"class":53},[25,711,622],{"class":31},[25,713,43],{"class":31},[25,715,110],{"class":31},[25,717,629],{"class":31},[25,719,720],{"class":42},"time.",[25,722,723],{"class":35},"After",[25,725,61],{"class":157},[25,727,728],{"class":348},"3",[25,730,731],{"class":31}," *",[25,733,734],{"class":42}," time.Second",[25,736,64],{"class":157},[25,738,641],{"class":42},[25,740,741,743,745,747,749,751,753,755,758,760,762,764],{"class":27,"data-line":306,"line":306},[25,742,54],{"class":53},[25,744,54],{"class":53},[25,746,285],{"class":42},[25,748,340],{"class":35},[25,750,61],{"class":157},[25,752,352],{"class":293},[25,754,658],{"class":348},[25,756,757],{"class":293},", 数据库查询完成",[25,759,664],{"class":348},[25,761,352],{"class":293},[25,763,669],{"class":42},[25,765,93],{"class":157},[25,767,768,770,772],{"class":27,"data-line":311,"line":311},[25,769,54],{"class":53},[25,771,20],{"class":42},[25,773,122],{"class":60},[25,775,776],{"class":27,"data-line":320,"line":320},[25,777,122],{"class":46},[25,779,780],{"class":27,"data-line":328,"line":328},[25,781,260],{"emptyLinePlaceholder":259},[25,783,784,786,789,791,793,795,797,799,801,803],{"class":27,"data-line":333,"line":333},[25,785,223],{"class":31},[25,787,788],{"class":35}," func2",[25,790,61],{"class":46},[25,792,419],{"class":71},[25,794,586],{"class":35},[25,796,78],{"class":42},[25,798,183],{"class":35},[25,800,64],{"class":46},[25,802,43],{"class":42},[25,804,47],{"class":46},[25,806,807,809,811,813,815,818,821,823,825,828,830,832,834,836,838,841,843,845,847,850,852],{"class":27,"data-line":366,"line":366},[25,808,54],{"class":53},[25,810,285],{"class":42},[25,812,340],{"class":35},[25,814,61],{"class":60},[25,816,817],{"class":293},"\"ctx.Value(",[25,819,820],{"class":348},"\\\"",[25,822,595],{"class":293},[25,824,820],{"class":348},[25,826,827],{"class":293},").(string): ",[25,829,349],{"class":348},[25,831,352],{"class":293},[25,833,355],{"class":42},[25,835,147],{"class":35},[25,837,61],{"class":157},[25,839,840],{"class":293},"\"name\"",[25,842,64],{"class":157},[25,844,78],{"class":42},[25,846,61],{"class":157},[25,848,849],{"class":31},"string",[25,851,64],{"class":157},[25,853,93],{"class":60},[25,855,856],{"class":27,"data-line":371,"line":371},[25,857,122],{"class":46},[25,859,861],{"class":27,"data-line":860,"line":860},14,[25,862,260],{"emptyLinePlaceholder":259},[25,864,866,868,871,873,875,877],{"class":27,"data-line":865,"line":865},15,[25,867,223],{"class":31},[25,869,870],{"class":35}," main",[25,872,61],{"class":46},[25,874,64],{"class":46},[25,876,43],{"class":42},[25,878,47],{"class":46},[25,880,882,884],{"class":27,"data-line":881,"line":881},16,[25,883,54],{"class":53},[25,885,886],{"class":316},"\u002F* ---------- context派生 ---------- *\u002F\n",[25,888,890,892,895,897,899,902,904,906],{"class":27,"data-line":889,"line":889},17,[25,891,54],{"class":53},[25,893,894],{"class":42},"ctx1, cancel ",[25,896,244],{"class":31},[25,898,247],{"class":42},[25,900,901],{"class":35},"WithCancel",[25,903,61],{"class":60},[25,905,408],{"class":42},[25,907,93],{"class":60},[25,909,911,913,915,917,919,922,925],{"class":27,"data-line":910,"line":910},18,[25,912,54],{"class":53},[25,914,19],{"class":31},[25,916,579],{"class":35},[25,918,61],{"class":60},[25,920,921],{"class":42},"ctx1, ",[25,923,924],{"class":293},"\"cancel\"",[25,926,93],{"class":60},[25,928,930,932,934,937,939,942,944,946],{"class":27,"data-line":929,"line":929},19,[25,931,54],{"class":53},[25,933,720],{"class":42},[25,935,936],{"class":35},"Sleep",[25,938,61],{"class":60},[25,940,941],{"class":348},"2",[25,943,731],{"class":31},[25,945,734],{"class":42},[25,947,93],{"class":60},[25,949,951,953,955,957,959,961],{"class":27,"data-line":950,"line":950},20,[25,952,54],{"class":53},[25,954,426],{"class":35},[25,956,61],{"class":60},[25,958,64],{"class":60},[25,960,43],{"class":42},[25,962,963],{"class":316},"\u002F\u002F 子goroutine 2s之后超时退出\n",[25,965,967],{"class":27,"data-line":966,"line":966},21,[25,968,260],{"emptyLinePlaceholder":259},[25,970,972,974,977,979,981,984,986,989,992,994,996,998,1001,1003,1006,1009,1012,1014],{"class":27,"data-line":971,"line":971},22,[25,973,54],{"class":53},[25,975,976],{"class":42},"ctx2, cancel2 ",[25,978,244],{"class":31},[25,980,247],{"class":42},[25,982,983],{"class":35},"WithDeadline",[25,985,61],{"class":60},[25,987,988],{"class":42},"parent, time.",[25,990,991],{"class":35},"Now",[25,993,61],{"class":157},[25,995,64],{"class":157},[25,997,78],{"class":42},[25,999,1000],{"class":35},"Add",[25,1002,61],{"class":157},[25,1004,1005],{"class":348},"1",[25,1007,1008],{"class":31},"*",[25,1010,1011],{"class":42},"time.Second",[25,1013,64],{"class":157},[25,1015,93],{"class":60},[25,1017,1019,1021,1023,1025,1027,1030,1033,1035,1037],{"class":27,"data-line":1018,"line":1018},23,[25,1020,54],{"class":53},[25,1022,19],{"class":31},[25,1024,579],{"class":35},[25,1026,61],{"class":60},[25,1028,1029],{"class":42},"ctx2, ",[25,1031,1032],{"class":293},"\"deadline\"",[25,1034,64],{"class":60},[25,1036,43],{"class":42},[25,1038,1039],{"class":316},"\u002F\u002F 子goroutine 1s之后超时退出\n",[25,1041,1043,1045,1048,1051,1053],{"class":27,"data-line":1042,"line":1042},24,[25,1044,54],{"class":53},[25,1046,1047],{"class":31},"defer",[25,1049,1050],{"class":35}," cancel2",[25,1052,61],{"class":60},[25,1054,93],{"class":60},[25,1056,1058],{"class":27,"data-line":1057,"line":1057},25,[25,1059,260],{"emptyLinePlaceholder":259},[25,1061,1063,1065,1068,1070,1072,1075,1077,1080,1083,1085,1088],{"class":27,"data-line":1062,"line":1062},26,[25,1064,54],{"class":53},[25,1066,1067],{"class":42},"ctx3, cancel3 ",[25,1069,244],{"class":31},[25,1071,247],{"class":42},[25,1073,1074],{"class":35},"WithTimeout",[25,1076,61],{"class":60},[25,1078,1079],{"class":42},"parent, ",[25,1081,1082],{"class":348},"500",[25,1084,1008],{"class":31},[25,1086,1087],{"class":42},"time.Millisecond",[25,1089,93],{"class":60},[25,1091,1093,1095,1097,1099,1101,1104,1107,1109,1111],{"class":27,"data-line":1092,"line":1092},27,[25,1094,54],{"class":53},[25,1096,19],{"class":31},[25,1098,579],{"class":35},[25,1100,61],{"class":60},[25,1102,1103],{"class":42},"ctx3, ",[25,1105,1106],{"class":293},"\"timeout\"",[25,1108,64],{"class":60},[25,1110,43],{"class":42},[25,1112,1113],{"class":316},"\u002F\u002F 子goroutine 0.5s之后超时退出\n",[25,1115,1117,1119,1121,1124,1126],{"class":27,"data-line":1116,"line":1116},28,[25,1118,54],{"class":53},[25,1120,1047],{"class":31},[25,1122,1123],{"class":35}," cancel3",[25,1125,61],{"class":60},[25,1127,93],{"class":60},[25,1129,1131],{"class":27,"data-line":1130,"line":1130},29,[25,1132,260],{"emptyLinePlaceholder":259},[25,1134,1136,1138,1141,1143,1145,1148,1150,1152,1154,1156,1159],{"class":27,"data-line":1135,"line":1135},30,[25,1137,54],{"class":53},[25,1139,1140],{"class":42},"ctx4 ",[25,1142,244],{"class":31},[25,1144,247],{"class":42},[25,1146,1147],{"class":35},"WithValue",[25,1149,61],{"class":60},[25,1151,1079],{"class":42},[25,1153,840],{"class":293},[25,1155,84],{"class":42},[25,1157,1158],{"class":293},"\"codepzj\"",[25,1160,93],{"class":60},[25,1162,1164,1166,1168,1170,1172,1175],{"class":27,"data-line":1163,"line":1163},31,[25,1165,54],{"class":53},[25,1167,19],{"class":31},[25,1169,788],{"class":35},[25,1171,61],{"class":60},[25,1173,1174],{"class":42},"ctx4",[25,1176,93],{"class":60},[25,1178,1180],{"class":27,"data-line":1179,"line":1179},32,[25,1181,260],{"emptyLinePlaceholder":259},[25,1183,1185,1187,1189,1191,1193,1196,1198,1200],{"class":27,"data-line":1184,"line":1184},33,[25,1186,54],{"class":53},[25,1188,720],{"class":42},[25,1190,936],{"class":35},[25,1192,61],{"class":60},[25,1194,1195],{"class":348},"5",[25,1197,731],{"class":31},[25,1199,734],{"class":42},[25,1201,93],{"class":60},[25,1203,1205],{"class":27,"data-line":1204,"line":1204},34,[25,1206,122],{"class":46},[178,1208,1209],{},"输出结果：",[15,1211,1214],{"className":1212,"code":1213,"language":382,"meta":20},[380],"ctx.Value(\"name\").(string): codepzj\ncancel, 超时了, 准备退出...\nctx.Err context canceled\ntimeout, 超时了, 准备退出...\nctx.Err context deadline exceeded\ndeadline, 超时了, 准备退出...\nctx.Err context deadline exceeded\n",[22,1215,1213],{"__ignoreMap":20},[10,1217,1219],{"id":1218},"context-用途","context 用途",[178,1221,1222],{},"context 主要有两个用途，也是在项目中经常使用的:",[1224,1225,1226,1229],"ol",{},[189,1227,1228],{},"用于并发控制，控制协程的优雅退出",[189,1230,1231],{},"上下文的信息传递，总的来说，context 就是用来在父子 goroutine 间进行值传递以及发送 cancel 信号的一种机制。",[1233,1234,1235],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sSDpw, html code.shiki .sSDpw{--shiki-default:#005cc5;--shiki-dark:#79b8ff}html pre.shiki code .sJX2D, html code.shiki .sJX2D{--shiki-default:#e36209;--shiki-dark:#ffab70}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sqkie, html code.shiki .sqkie{--shiki-default:#5a32a3;--shiki-dark:#b392f0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":20,"searchDepth":125,"depth":125,"links":1237},[1238,1239,1240,1241],{"id":12,"depth":50,"text":13},{"id":203,"depth":50,"text":204},{"id":390,"depth":50,"text":391},{"id":1218,"depth":50,"text":1219},[1243],"Go语言","2025-08-20","Go语言的context包是并发编程的核心工具，主要用于管理goroutine的生命周期、传递取消信号和请求范围数据。通过WithCancel、WithTimeout、WithDeadline和WithValue等方法，可以从根context派生出子context，形成树状结构，实现优雅的协程控制和超时管理。context广泛应用于HTTP请求、数据库操作等场景，确保资源及时释放，避免泄漏。最佳实践包括及时调用cancel()、避免滥用WithValue传递业务参数，以及在goroutine中监听ctx.Done()以响应取消信号",false,"md",null,{"slots":1250},{},"\u002F2025\u002F08\u002Fgo-context1",{"text":1253,"minutes":1254,"time":1255,"words":1256},"4 min read",3.64,218400,728,{"title":5,"description":1245},{"loc":1251},"posts\u002F2025\u002F08\u002Fgo-context1",[563],"tech","YtD6wjas3aF4WC-9HOKhC-I5FWwT1tnm-21CW2UQ808",[1264,1269],{"title":1265,"path":1266,"stem":1267,"date":1268,"type":1261,"children":-1},"go jwt和redis实现用户登录注册以及查询","\u002F2025\u002F08\u002Fgo-jwt-redis-demo","posts\u002F2025\u002F08\u002Fgo-jwt-redis-demo","2025-08-08",{"title":1270,"path":1271,"stem":1272,"date":1273,"type":1261,"children":-1},"Go 反射机制详解","\u002F2025\u002F08\u002Fgo-reflect","posts\u002F2025\u002F08\u002Fgo-reflect","2025-08-21",1786555056330]