Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ThreadLocal for Golang.

License

NotificationsYou must be signed in to change notification settings

timandy/routine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Build StatusCodecovGo Report CardDocumentationReleaseLicense

中文版

routine encapsulates and provides some easy-to-use, non-competitive, high-performancegoroutine context access interfaces, which can help you access coroutine context information more gracefully.

🏠Introduce

From the very beginning of its design, theGolang language has spared no effort to shield the concept of coroutine context from developers, including the acquisition of coroutinegoid, the state of coroutine within the process, and the storage of coroutine context.

If you have used other languages such asC++,Java and so on, then you must be familiar withThreadLocal, but after starting to useGolang, you will be deeply confused and distressed by the lack of convenient functions likeThreadLocal.

Of course, you can choose to useContext, which carries all the context information, appears in the first input parameter of all functions, and then shuttles around your system.

And the core goal ofroutine is to open up another way: Introducegoroutine local storage to theGolang world.

📢Update Notice

🔥Version1.1.5 introduces a new static mode.

  • 🚀Performance improved by over20%.

  • 🚀Memory access is now safer.

  • ❗The compile command requires additional parameters-a -toolexec='routinex -v'.

For more details, visit:RoutineX Compiler

🛠️Usage & Demo

This chapter briefly introduces how to install and use theroutine library.

Install

go get github.com/timandy/routine

Usegoid

The following code simply demonstrates the use ofroutine.Goid():

package mainimport ("fmt""time""github.com/timandy/routine")funcmain() {goid:=routine.Goid()fmt.Printf("cur goid: %v\n",goid)gofunc() {goid:=routine.Goid()fmt.Printf("sub goid: %v\n",goid)}()// Wait for the sub-coroutine to finish executing.time.Sleep(time.Second)}

In this example, themain function starts a new coroutine, soGoid() returns the main coroutine1 and the child coroutine6:

cur goid: 1sub goid: 6

UseThreadLocal

The following code briefly demonstratesThreadLocal's creation, setting, getting, spreading across coroutines, etc.:

package mainimport ("fmt""time""github.com/timandy/routine")varthreadLocal=routine.NewThreadLocal[string]()varinheritableThreadLocal=routine.NewInheritableThreadLocal[string]()funcmain() {threadLocal.Set("hello world")inheritableThreadLocal.Set("Hello world2")fmt.Println("threadLocal:",threadLocal.Get())fmt.Println("inheritableThreadLocal:",inheritableThreadLocal.Get())// The child coroutine cannot read the previously assigned "hello world".gofunc() {fmt.Println("threadLocal in goroutine:",threadLocal.Get())fmt.Println("inheritableThreadLocal in goroutine:",inheritableThreadLocal.Get())}()// However, a new sub-coroutine can be started via the Go/GoWait/GoWaitResult function, and all inheritable variables of the current coroutine can be passed automatically.routine.Go(func() {fmt.Println("threadLocal in goroutine by Go:",threadLocal.Get())fmt.Println("inheritableThreadLocal in goroutine by Go:",inheritableThreadLocal.Get())})// You can also create a task via the WrapTask/WrapWaitTask/WrapWaitResultTask function, and all inheritable variables of the current coroutine can be automatically captured.task:=routine.WrapTask(func() {fmt.Println("threadLocal in task by WrapTask:",threadLocal.Get())fmt.Println("inheritableThreadLocal in task by WrapTask:",inheritableThreadLocal.Get())})gotask.Run()// Wait for the sub-coroutine to finish executing.time.Sleep(time.Second)}

The execution result is:

threadLocal: hello worldinheritableThreadLocal: Hello world2threadLocal in goroutine:inheritableThreadLocal in goroutine:threadLocal in goroutine by Go:inheritableThreadLocal in goroutine by Go: Hello world2threadLocal in task by WrapTask:inheritableThreadLocal in task by WrapTask: Hello world2

📚API

This chapter introduces in detail all the interfaces encapsulated by theroutine library, as well as their core functions and implementation methods.

Goid() uint64

Get thegoid of the currentgoroutine.

It can be obtained directly through assembly code under386,amd64,armv6,armv7,arm64,loong64,mips,mipsle,mips64,mips64le,ppc64,ppc64le,riscv64,s390x,wasm architectures. This operation has extremely high performance and the time-consuming is usually only one-fifth ofrand.Int().

NewThreadLocal[T any]() ThreadLocal[T]

Create a newThreadLocal[T] instance with the initial value stored with the default value of typeT.

NewThreadLocalWithInitial[T any](supplier Supplier[T]) ThreadLocal[T]

Create a newThreadLocal[T] instance with the initial value stored as the return value of the methodsupplier().

NewInheritableThreadLocal[T any]() ThreadLocal[T]

Create a newThreadLocal[T] instance with the initial value stored with the default value of typeT.When a new coroutine is started viaGo(),GoWait() orGoWaitResult(), the value of the current coroutine is copied to the new coroutine.When a new task is created viaWrapTask(),WrapWaitTask() orWrapWaitResultTask(), the value of the current coroutine is captured to the new task.

NewInheritableThreadLocalWithInitial[T any](supplier Supplier[T]) ThreadLocal[T]

Create a newThreadLocal[T] instance with the initial value stored as the return value of the methodsupplier().When a new coroutine is started viaGo(),GoWait() orGoWaitResult(), the value of the current coroutine is copied to the new coroutine.When a new task is created viaWrapTask(),WrapWaitTask() orWrapWaitResultTask(), the value of the current coroutine is captured to the new task.

WrapTask(fun Runnable) FutureTask[any]

Create a new task and capture theinheritableThreadLocals from the current goroutine.This function returns aFutureTask instance, but the return task will not run automatically.You can run it in a sub-goroutine or goroutine-pool byFutureTask.Run() method, wait byFutureTask.Get() orFutureTask.GetWithTimeout() method.When the returned task runpanic will be caught and error stack will be printed, thepanic will be trigger again when callingFutureTask.Get() orFutureTask.GetWithTimeout() method.

WrapWaitTask(fun CancelRunnable) FutureTask[any]

Create a new task and capture theinheritableThreadLocals from the current goroutine.This function returns aFutureTask instance, but the return task will not run automatically.You can run it in a sub-goroutine or goroutine-pool byFutureTask.Run() method, wait byFutureTask.Get() orFutureTask.GetWithTimeout() method.When the returned task runpanic will be caught, thepanic will be trigger again when callingFutureTask.Get() orFutureTask.GetWithTimeout() method.

WrapWaitResultTask[TResult any](fun CancelCallable[TResult]) FutureTask[TResult]

Create a new task and capture theinheritableThreadLocals from the current goroutine.This function returns aFutureTask instance, but the return task will not run automatically.You can run it in a sub-goroutine or goroutine-pool byFutureTask.Run() method, wait and get result byFutureTask.Get() orFutureTask.GetWithTimeout() method.When the returned task runpanic will be caught, thepanic will be trigger again when callingFutureTask.Get() orFutureTask.GetWithTimeout() method.

Go(fun Runnable)

Start a new coroutine and automatically copy all contextualinheritableThreadLocals data of the current coroutine to the new coroutine.Anypanic while the child coroutine is executing will be caught and the stack automatically printed.

GoWait(fun CancelRunnable) FutureTask[any]

Start a new coroutine and automatically copy all contextualinheritableThreadLocals data of the current coroutine to the new coroutine.You can wait for the sub-coroutine to finish executing through theFutureTask.Get() orFutureTask.GetWithTimeout() method that returns a value.Anypanic while the child coroutine is executing will be caught and thrown again whenFutureTask.Get() orFutureTask.GetWithTimeout() is called.

GoWaitResult[TResult any](fun CancelCallable[TResult]) FutureTask[TResult]

Start a new coroutine and automatically copy all contextualinheritableThreadLocals data of the current coroutine to the new coroutine.You can wait for the sub-coroutine to finish executing and get the return value through theFutureTask.Get() orFutureTask.GetWithTimeout() method of the return value.Anypanic while the child coroutine is executing will be caught and thrown again whenFutureTask.Get() orFutureTask.GetWithTimeout() is called.

More API Documentation

🗑️Garbage Collection

routine allocates athread structure for each coroutine, which stores context variable information related to the coroutine.

A pointer to this structure is stored on theg.labels field of the coroutine structure.

When the coroutine finishes executing and exits,g.labels will be set tonil, no longer referencing thethread structure.

Thethread structure will be collected at the nextGC.

If the data stored inthread is not additionally referenced, these data will be collected together.

🌐Support Grid

darwinlinuxwindowsfreebsdjs
386386
amd64amd64
armv6armv6
armv7armv7
arm64arm64
loong64loong64
mipsmips
mipslemipsle
mips64mips64
mips64lemips64le
ppc64ppc64
ppc64leppc64le
riscv64riscv64
s390xs390x
wasmwasm
darwinlinuxwindowsfreebsdjs

✅: Supported

🙏Thanks

Thanks to allcontributors for their contributions!

📜License

routine is released under theApache License 2.0.

Copyright 2021-2025 TimAndyLicensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License at    https://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.

[8]ページ先頭

©2009-2025 Movatter.jp