1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
package main
import ( "fmt" "os" "plugin" "strings" "sync" "time" )
var ( fn func() // plugin 动态加载的函数 fnLock sync.RWMutex )
func main() {
tick := time.NewTicker(time.Second) inputCh := readInput()
for { select { case <-tick.C: execFn() case file := <-inputCh: fmt.Printf("loading plugin file : %s\n", file) load(file) } } }
func readInput() <-chan string { ch := make(chan string, 1) go func() { b := make([]byte, 16) for { n, err := os.Stdin.Read(b) if err != nil { } if n > 0 { ch <- string(b[:n]) } } }() return ch }
func load(file string) { file = strings.TrimSpace(file) p, err := plugin.Open("./myplugin/" + file) if err != nil { fmt.Printf("Open plugin error: %v\n", err) return } sb, err := p.Lookup("Print") if err != nil { fmt.Printf("plugin lookup failed, error: %v\n", err) return } nfn, _ := sb.(func())
fnLock.Lock() fn = nfn fnLock.Unlock() }
func execFn() { if fn != nil { fnLock.RLock() defer fnLock.RUnlock() fn() } }
|