当前位置:网站首页>Hello go (XIII). Go language common standard library III
Hello go (XIII). Go language common standard library III
2022-06-11 17:58:00 【Tianshan old demon】
One 、sync
1、sync brief introduction
sync Provides basic synchronization primitives , Such as sync.Mutex,sync.RWMutex,sync.Once,sync.Cond,sync.Waitgroup, except Once and WaitGroup Out of type , Most types are used by low-level libraries .Go In language , Do not communicate through shared memory , And to share memory through communication , adopt Channel And communication can better complete higher-level synchronization .
type Locker interface {
Lock()
Unlock()
}Locker Two operation methods of lock are provided ,Lock、Unlock.
2、sync.Mutex
sync.Mutex It's a mutex , yes Locker An implementation of .
A mutex can only be locked by one at the same time goroutine lock , Other goroutine Will block until the mutex is unlocked ( Re contention for lock on mutex ).
sync.Mutex Use caution :
(1) Do not copy mutexes after first use .
(2) Unlocking an unlocked mutex will result in a runtime error .
Examples of use :
package main
import (
"fmt"
"sync"
"time"
)
var locker sync.Mutex
func mutexDemo() {
var value int = 0
for i := 0; i < 100; i++ {
go func(i int) {
locker.Lock()
defer locker.Unlock()
fmt.Printf("Goroutine %d : value: %d\n", i, value)
value++
}(i)
}
}
func main() {
mutexDemo()
time.Sleep(time.Second)
}3、sync.Pool
sync.Pool The temporary object pool is used to store temporary objects , Store the used objects in the object pool , Take it out and reuse it when you need it , The purpose is to avoid creating the same object repeatedly GC Overburdened . If the object is no longer referenced by other variables , Stored temporary objects may be GC Recycle .
type Pool struct {
// Functions that create temporary objects
New func() interface{}
}
// Store objects into the temporary object pool
func (p *Pool) Put(x interface{})
// Fetch objects from the temporary object pool
func (p *Pool) Get() interface{}from sync.Pool When the object is taken out of the , If Pool There are no objects in , Will return nil, But if you give Pool.New Field specifies a function ,Pool A new object will be created using the specified function to return .
sync.Pool It can be safely used in multiple goroutine In parallel , But it does not apply to all idle objects , Temporary objects that should be used to manage concurrent routine sharing , Instead of managing temporary objects in short-lived objects .
sync.Pool An example is as follows :
package main
import (
"bytes"
"io"
"os"
"sync"
"time"
)
var bufPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
func Log(w io.Writer, key, val string) {
// Get temporary objects , If not, create it automatically
b := bufPool.Get().(*bytes.Buffer)
b.Reset()
b.WriteString(time.Now().Format(time.RFC3339))
b.WriteByte(' ')
b.WriteString(key)
b.WriteByte('=')
b.WriteString(val)
w.Write(b.Bytes())
// Put the temporary object back to Pool in
bufPool.Put(b)
}
func main() {
Log(os.Stdout, "key", "value")
}
// output:
// 2018-12-31T15:57:27+08:00 key=value4、sync.Once
sync.Once You can make the function execute only once after multiple calls .
type Once struct {
m Mutex
done uint32
}
func (o *Once) Do(f func())use done To record the number of executions , Use a mutex m To ensure that it is executed only once . only one Do Method , Calls to perform .
utilize sync.Once The code to implement the singleton mode is as follows :
package Singleton
import (
"sync"
)
type Singleton map[string]string
var (
instance Singleton
once sync.Once
)
func New() Singleton{
once.Do(func() {
instance = make(Singleton)
})
return instance
}An example is as follows :
package main
import (
"fmt"
"DesignPattern/Singleton"
)
func main() {
instance1 := Singleton.New()
instance1["name"] = "Jack Bauer"
instance2 := Singleton.New()
fmt.Println("My name is", instance2["name"])
}
// output:
// My name is Jack Bauer5、sync.RWMutex
sync.RWMutex Is a mutex for read / write operations , The biggest difference between read-write lock and mutex lock is that they can read and write separately 、 Write to lock . It is generally used in a large number of read operations 、 A small number of write operations .sync.RWMutex Four operation methods are provided :
func (rw *RWMutex) Lock()
func (rw *RWMutex) Unlock()
func (rw *RWMutex) RLock()
func (rw *RWMutex) RUnlock()RLock Lock the read operation ,RUnlock Unlock the read lock ,Lock Lock the write operation ,Unlock Unlock the write lock .
sync.RWMutex The locking rules are as follows :
(1) There can only be one at a time goroutine Can get write lock .
(2) There can be any number of gorouinte Get read lock .
(3) At the same time, only write lock or read lock can exist ( Reading and writing are mutually exclusive ).
(4) When you have one goroutine Get a write lock , Others, whether read lock or write lock, will be blocked until write is unlocked ; When you have one goroutine Get read lock , Other read locks can still continue ; When there is one or more read locks , The write lock will wait until all the read locks are unlocked before the write lock can be performed .
sync.RWMutex Pay attention to the use of read-write locks :
(1) After first use , Do not duplicate read / write locks .
(2) Don't mix lock and unlock , Such as :Lock and RUnlock、RLock and Unlock. Unlocking the read-write lock without read lock or unlocking the read-write lock without write lock will cause runtime error .
Use sample code :
package main
import (
"fmt"
"sync"
"time"
)
var rw sync.RWMutex
func RWMutexDemo() {
var value int = 0
for i := 0; i < 10; i++ {
go func(i int) {
rw.Lock()
defer rw.Unlock()
fmt.Printf("Goroutine %d : Write value: %d\n", i, value)
value++
}(i)
go func(i int) {
rw.RLock()
defer rw.RUnlock()
fmt.Printf("Goroutine %d : Read value: %d\n", i, value)
}(i)
}
}
func main() {
RWMutexDemo()
time.Sleep(time.Minute)
}6、sync.WaitGroup
sync.WaitGroup Used to wait for a group goroutine end .
sync.WaitGroup The operation method is as follows :
func (wg *WaitGroup) Add(delta int)
func (wg *WaitGroup) Done()
func (wg *WaitGroup) Wait()Add Used to add goroutine The number of .Done Perform a quantity reduction 1.Wait Used to wait for the end .
sync.WaitGroup An example is as follows :
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func WaitGroupDemo() {
var value int = 0
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Printf("Goroutine %d : Write value: %d\n", i, value)
value++
}(i)
wg.Add(1)
go func(i int) {
defer wg.Done()
fmt.Printf("Goroutine %d : Read value: %d\n", i, value)
}(i)
}
}
func main() {
WaitGroupDemo()
wg.Wait()
}7、sync.Cond
sync.Cond Implement a conditional wait variable , I.e. waiting for or announcing the occurrence of the event goroutine Meeting point of .
func NewCond(l Locker) *Cond
func (c *Cond) Broadcast()
func (c *Cond) Signal()
func (c *Cond) Wait()NewCond For use in accordance with Locker Create a conditional wait variable ,Wait Used to make a goroutine Wait for a notice ,Signal It is used to send a notification in a single time to make the waiting goroutine continue ,Broadcast Used to broadcast notifications to keep all waiting goroutine continue .
sync.Cond The conditional wait variable implements the producer - Examples of consumer patterns are as follows :
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var locker = new(sync.Mutex)
var cond = sync.NewCond(locker)
var capacity = 10
var consumerNum = 5
var producerNum = 2
func Produce(out chan<- int) {
for i := 0; i < producerNum; i++ {
go func(nu int) {
for {
cond.L.Lock()
for len(out) == capacity {
fmt.Println("Capacity Full, stop Produce")
cond.Wait()
}
num := rand.Intn(100)
out <- num
fmt.Printf("Producer %d produce: num %d\n", nu, num)
cond.L.Unlock()
cond.Signal()
time.Sleep(time.Microsecond * 500)
}
}(i)
}
}
func Consume(in <-chan int) {
for i := 0; i < consumerNum; i++ {
go func(nu int) {
for {
cond.L.Lock()
for len(in) == 0 {
fmt.Println("Capacity Empty, stop Consume")
cond.Wait()
}
num := <-in
fmt.Printf("Consumer %d: consume num %d\n", nu, num)
cond.L.Unlock()
time.Sleep(time.Second)
cond.Signal()
}
}(i)
}
}
func main() {
rand.Seed(time.Now().UnixNano())
quit := make(chan bool)
ProductPool := make(chan int, capacity)
Produce(ProductPool)
Consume(ProductPool)
<-quit
}Two 、reflect
1、reflect brief introduction
In the field of Computer Science , Reflection refers to applications that are self describing and self controlling . Reflection uses some mechanism to describe its own behavior (self-representation) And monitoring (examination), And according to the state and result of their own behavior , Adjust or modify the state and related semantics of the behavior described by the application .
Each language has a different reflection model , And some languages do not support reflection .Golang Language passing reflect The package implements the reflection mechanism , Dynamically call methods and properties of objects at run time .
Go Variables in the language include (type, value) Two parts ,type Include static type and concrete type.static typ Is the type of encoding ( Such as int、string),concrete type yes runtime The type of .
Whether the type assertion can succeed , Depends on the of the variable concrete type, instead of static type. therefore , One reader Variable if it concrete type Realized write Method , It can also be asserted by type as writer.
Golang Specifies that the type of the type variable is static , The type is determined when the variable is created , therefore , Reflection is mainly related to Golang Of interface Type related (type yes concrete type).
stay Golang In the implementation of , Every interface Every variable has a (value, type) For actual values and types used to record variables .value Is the actual value of the variable ,type Is the actual type of the variable .interface Variables of type include 2 A pointer to the , A pointer to the type of value (concrete type), The other pointer points to the actual value (value).
2、reflect Interface
func TypeOf(i interface{}) TypeTypeOf The type used to dynamically obtain the value in the input parameter interface , If the interface is empty, return nil.
func ValueOf(i interface{}) ValueValueOf Used to obtain the value of data in the input parameter interface , If the interface is empty, return 0.
reflect.ValueOf(interface) Get one relfect.Value Variable , Can pass relfect.Value Of itself Interface() Method to get the real content of the interface variable , You can then convert by type judgment , Convert to the original real type . The real type may be a known old type , It may also be an unknown original type .
For known legacy types :
package main
import (
"fmt"
"reflect"
)
func main() {
var num float64 = 3.14
value := reflect.ValueOf(num)
pointer := reflect.ValueOf(&num)
fmt.Println("value: ", value.Interface().(float64))
fmt.Println("value: ", pointer.Interface().(*float64))
fmt.Println("type: ", reflect.TypeOf(num))
}
// output:
// value: 3.14
// value: 0xc42001e0e8
// type: float64For unknown legacy types , You need to traverse to detect its Filed:
package main
import (
"fmt"
"reflect"
)
type Student struct {
Name string
ID int
Age int
}
func (student Student) Print() {
fmt.Printf("%s's ID is %d, %d years.", student.Name, student.ID, student.Age)
}
func handleFieldAndMethod(input interface{}) {
inputType := reflect.TypeOf(input)
fmt.Println("type: ", inputType.Name())
inputValue := reflect.ValueOf(input)
fmt.Println("value: ", inputValue)
// Get method field
// 1. First get interface Of reflect.Type, And then through NumField Traversal
// 2. Re pass reflect.Type Of Field Get its Field
// 3. Finally through Field Of Interface() Get the corresponding value
for i := 0; i < inputType.NumField(); i++ {
field := inputType.Field(i)
value := inputValue.Field(i).Interface()
fmt.Printf("%s %v %v\n", field.Name, field.Type, value)
}
// Access method
// 1. First get interface Of reflect.Type, And then through .NumMethod Traversal
for i := 0; i < inputType.NumMethod(); i++ {
m := inputType.Method(i)
fmt.Printf("%s: %v\n", m.Name, m.Type)
}
}
func main() {
bauer := Student{"Bauer", 1, 130}
handleFieldAndMethod(bauer)
}
// output:
// type: Student
// value: {Bauer 1 130}
// Name string Bauer
// ID int 1
// Age int 130
// Print: func(main.Student)func (v Value) MethodByName(name string) ValueMethodByName Returns a function value corresponding to reflect.Value The name of the method .
func (v Value) Call(in []Value) []ValueCall Method will eventually call the real method , The parameters must be consistent .
package main
import (
"fmt"
"reflect"
)
type Student struct {
Name string
ID int
Age int
}
func (student Student) Print() {
fmt.Printf("%s's ID is %d, %d years.", student.Name, student.ID, student.Age)
}
func CallMethod() {
student := Student{"Bauer", 1, 20}
value := reflect.ValueOf(student)
methodValue := value.MethodByName("Print")
// For nonparametric functions
args := make([]reflect.Value, 0)
methodValue.Call(args)
}
func main() {
CallMethod()
}
// output:
// Print: func(main.Student)3、 ... and 、runtime
1、runtime brief introduction
Go The language compiler produces native executable code , The executable code still runs in Go Of runtime in ,runtime Responsible for management including memory allocation 、 Garbage collection 、 Stack processing 、goroutine、channel、 section (slice)、map And reflection (reflection) etc. .
runtime And C The role of the standard library is the same for the cross platform of the language ,runtime Can run in Windows and Unix platform , Can run in Intel or ARM On the processor .Go The program comes with runtime,runtime Responsible for interacting with the underlying operating system .
2、runtime Common methods
runtime.Gosched()Let the current goroutine Give up cpu So that others goroutine function , The current thread will not be suspended , Therefore, the current thread will continue to execute in the future .
func NumCPU() intGet the logic of the current system CPU Nuclear quantity
runtime.GOMAXPROCS(i int)Set the maximum number of simultaneous CPU
adopt runtime.GOMAXPROCS function , How applications set up logical processors in the runtime system during runtime P The largest number . Should be called at the earliest in the application . And the best settings P The maximum method is to run Go Set the environment variables of the operating program before the program GOMAXPROCS, Instead of calling... In a program runtime.GOMAXPROCS function .
No matter what the integer value passed to the function is , Runtime system P The maximum value will always be 1~256 Between .
runtime.Goexit()Quit current goroutine( but defer The statement will execute as usual )
runtime.Goexit After function is called , Will immediately invoke his Groution The operation of was terminated , But other Goroutine It won't be affected .runtime.Goexit The function is terminating the call to it Goroutine The... Will be executed before the operation of Groution Which has not been implemented in defer sentence .
runtime.NumGoroutine()Get the total number of tasks being executed and queued
runtime.NumGoroutine Function after being called , Will return the in a specific state in the system Goroutine The number of . Here refers specifically to Grunnable\Gruning\Gsyscall\Gwaition. In these States Groutine That is, it is regarded as active or being scheduled .
Be careful : Where the garbage is collected Groutine If the state of is also within this range , Will also be included in the counter .
runtime.GOOSGet the target operating system
func GOROOT() stringGet current GOROOT
3、cgo
CGO It's the realization of Go And C Ways to interoperate , Include Go transfer C and C transfer Go Two processes .Go call C A pseudo package that needs to be introduced into the program ,import “C” That is in Go Pseudo package used in .C The pseudo package will be CGO The tool captures , And do some code rewriting and pile file generation , It won't be Go The compiler sees .
Go Call in language C The procedure is as follows :
// Custom function call
package main
/*
#include <stdio.h>
#include <stdlib.h>
void output(char *str) {
printf("%s\n", str);
}
*/
import "C"
import "unsafe"
func main() {
str := C.CString("hello cgo")
C.output(str)
C.free(unsafe.Pointer(str))
}4、 Scheduler
every last Go The program comes with a runtime,runtime Responsible for interacting with the underlying operating system , There will be scheduler Yes goruntines To schedule .
Four 、plugin
1、plugin brief introduction
Golang Is a statically compiled language , At compile time, all referenced packages are loaded and packaged into the final executable program , Therefore, you cannot dynamically load other shared libraries at run time .Go 1.8 Start ,Go Language Linux and MacOS Version passed plugin Package provides a plug-in mechanism for loading shared libraries , Be able to dynamically load external functions at runtime .
2、plugin Common methods
type Plugin struct {
pluginpath string
err string // set if plugin failed to load
loaded chan struct{} // closed when loaded
syms map[string]interface{}
}
func Open(path string) (*Plugin, error)
func (p *Plugin) Lookup(symName string) (Symbol, error)
type Symbol interface{}Open: According to the parameters path The provided plug-in path loads the plug-in , And return a pointer to the plug-in structure *Plugin.
Lookup: *Plugin The only way to , By name symName Find the corresponding variable or method in the plug-in , With Symbol Form return of . Any element found in the plug-in is preceded by Symbol form ( namely interface{}) return , The results need to be judged and transformed in the form of assertions , Get the type you need .
3、 Plug in compilation method
Go The language compiler uses -buildmode=plugin Markup compilation generates a plug-in ( Shared object library files ).Go The exported functions and variables in the package are exposed as ELF Symbol , have access to plugin Packages find and bind at run time ELF Symbol .
go build -buildmode=plugin -o xxxplugin.so xxxplugin.goIf you want to better control the plug-in version , Implement the hot update plug-in , You can register plug-ins automatically . When the new version of the plug-in is loaded , Automatically register the plug-in version number , The method of preferentially using new version plug-ins in the plug-in platform .
4、 Plug in usage example
Plug in writing HelloPlugin.go:
package main
import (
"fmt"
)
func init() {
fmt.Println("Hello")
}
func Hello() {
fmt.Println("world")
}Plug in compilation :
go build -buildmode=plugin -o HelloPlugin.so HelloPlugin.goPlug in call main.go:
package main
import (
"fmt"
"plugin"
)
func main() {
open, err := plugin.Open("./HelloPlugin.so")
if err != nil {
fmt.Println(err.Error())
}
symbol, err := open.Lookup("Hello")
if err != nil {
fmt.Println(err)
}
symbol.(func())()
}Compile operation :
go run main.go5、 Plug in programming
The plug-in manager implements :
package PluginManager
import "fmt"
// Plug in container
var Plugins map[string]Plugin
func init() {
Plugins = make(map[string]Plugin)
}
type Plugin interface {
Start()
}
// Start all the plug-ins in this container
func Start() {
for name, plugin := range Plugins {
go plugin.Start()
fmt.Printf("%s Plugin Start.\n", name)
}
}
// After the plug-in is finished, it must be inserted into the container
func Register(name string, plugin Plugin) {
Plugins[name] = plugin
}Plug-in implementation :
package HelloPlugin
import (
"GoExample/Plugin/PluginManager"
"fmt"
)
type HelloPlugin struct {
}
// Register plug-ins when importing packages
func init() {
plugin := HelloPlugin{}
PluginManager.Register("HelloPlugin", plugin)
}
func (this HelloPlugin) Start() {
fmt.Println("This is HelloPlugin.")
}The plug-in USES :
package main
import "GoExample/Plugin/PluginManager"
import _ "GoExample/Plugin/HelloPlugin"
func main() {
PluginManager.Start()
}
// output:
// HelloPlugin Plugin Start.5、 ... and 、signal
1、signal brief introduction
os/signal Packets can be used to process signals ,Notify Method to listen for a received signal ,Stop Method to cancel listening .
func Notify(c chan<- os.Signal, sig ...os.Signal)Notify Function will send the process to the system Signal Forward to channel c, Which signals to forward are determined by variable parameters ,SIGKILL and SIGSTOP Cannot be intercepted and processed .
Parameters c Indicates the of the received signal channel, Subsequent parameters indicate setting the signal to be monitored , If it is not set, it means that all signals are monitored .
func Stop(c chan<- os.Signal)Stop Method to cancel listening for all signals on the channel .
2、signal Example
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
signalChannel := make(chan os.Signal, 1)
done := make(chan bool, 1)
// monitor SIGINT、SIGTERM
signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM)
go func(ch chan os.Signal) {
// Received signal
channel := <-ch
fmt.Printf("Received a signal: %s\n", channel)
done <- true
}(signalChannel)
// signal.Stop(signalChannel)
for {
fmt.Println("Waiting signal.")
<-done
fmt.Println("Exiting.")
}
}边栏推荐
- mariadb spider分片引擎初體驗
- Tidb CDC log tables are not eligible to replicate
- Online excel file parsing and conversion to JSON format
- 6-7 文件读写操作
- [collect first and use it sooner or later] 49 Flink high-frequency interview questions series (I)
- [collect first and use it sooner or later] 100 Flink high-frequency interview questions series (I)
- Using packstack to quickly install openstack
- [collect first and use it sooner or later] 100 Flink high-frequency interview questions series (III)
- 6-8 reading and writing of structured files 1
- 【深度学习基础】神经网络的学习(3)
猜你喜欢

Ffmpeg hardware codec NVIDIA GPU

Service学习笔记02-实战 startService 与bindService

送给大模型的「高考」卷:442人联名论文给大模型提出204个任务,谷歌领衔

安装mariadb 10.5.7(tar包安装)

The tle6389 step-down DC-DC switch controller has high efficiency in the whole load range of 1mA to 2.5A - keshijin mall

Initial experience of MariaDB spider sharding engine

有效的括号---2022/02/23
![[foundation of deep learning] learning of neural network (3)](/img/a5/1b80ba85faf8fa636b784c76d4df2f.png)
[foundation of deep learning] learning of neural network (3)

ffmpeg奇偶场帧Interlace progressive命令和代码处理

Merge K ascending linked lists ---2022/02/26
随机推荐
Remove key lookup bookmark from SQL Server
Why is the UDP stream set to 1316 bytes
upload-labs通关未半而中道崩殂
Bracket generation ---2022/02/25
聚类方法汇总
Mathematical basis of information security Chapter 4 -- quadratic residual and square root
Tle6389-2g V50's unique pwm/pfm control scheme has a duty cycle of up to 100%, forming a very low differential pressure - keshijin mall
TestPattern error
ArrayList collection, object array
CentOS7服务器配置(四)---安装redis
Service learning notes 03 front desk service practice
MFSR:一种新的推荐系统多级模糊相似度量
System learning typescript (V) - joint type
mariadb spider分片引擎初體驗
6-8 创建、遍历链表
Hwang
删除链表的倒数第N个节点---2022/02/22
Use exe4j to convert The jar file is packaged as Exe file
7-2 h0107. Pig-Latin
[MySQL] detailed explanation of redo log, undo log and binlog (4)