PHP 混合 Go 协程并发

PHP 混合 Go 协程并发

想法很简单。通过设置 runtime.GOMAXPROCS(1) 让 golang 的进程变成单线程执行的。类似python用gevent的效果。然后通过调度多个协程实现异步I/O并发。php作为一个子函数跑在go的进程内,php需要yield到其他协程时,通过回调到golang函数来实现。从php里调用go提供的子函数时,go保证保存php的当前上下文。当协程执行权让渡回来的时候,把原来的php上下文恢复。关键的代码在:

// 保存当前协程上的php上下文
oldServerCtx := engine.ServerContextGet()
fmt.Println(oldServerCtx)
defer engine.ServerContextSet(oldServerCtx)
oldExecutorCtx := engine.ExecutorContextGet()
fmt.Println(oldExecutorCtx)
defer engine.ExecutorContextSet(oldExecutorCtx)
oldCoreCtx := engine.CoreContextGet()
fmt.Println(oldCoreCtx)
defer engine.CoreContextSet(oldCoreCtx)

// 放弃全局的锁,使得其他的协程可以开始执行php
engineLock.Unlock()
defer engineLock.Lock()
ServerContextGet 这几个函数是我加的,获得的是php的(EG/SG/PG)这三个全局context(参见: http://www.cnblogs.com/chance… )。修改过的php-go的源代码在: .http://www.jieba8.com/

完整的php/go混合协程的demo:

package main

import (
“fmt”
“github.com/deuill/go-php/engine”
“os”
“runtime”
“time”
“sync”
)

type TestObj struct{}

func newTestObj(args []interface{}) interface{} {
return &TestObj{}
}
var engineLock *sync.Mutex

func (self *TestObj) Hello() {
oldServerCtx := engine.ServerContextGet()
fmt.Println(oldServerCtx)
defer engine.ServerContextSet(oldServerCtx)
oldExecutorCtx := engine.ExecutorContextGet()
fmt.Println(oldExecutorCtx)
defer engine.ExecutorContextSet(oldExecutorCtx)
oldCoreCtx := engine.CoreContextGet()
fmt.Println(oldCoreCtx)
defer engine.CoreContextSet(oldCoreCtx)
engineLock.Unlock()
defer engineLock.Lock()
time.Sleep(time.Second)
fmt.Println(“sleep done”)
}

func main() {
runtime.GOMAXPROCS(1)
theEngine, err := engine.New()
engineLock = &sync.Mutex{}
if err != nil {
fmt.Println(err)
}
_, err = theEngine.Define(“TestObj”, newTestObj)
wg := &sync.WaitGroup{}
wg.Add(2)
before := time.Now()
fmt.Println(“1”)
go func() {
engineLock.Lock()
defer engineLock.Unlock()
context1, err := theEngine.NewContext()
if err != nil {
fmt.Println(err)
}
context1.Output = os.Stdout
if err != nil {
fmt.Println(err)
}
fmt.Println(“1 enter”)
_, err = context1.Eval("$testObj = new TestObj(); KaTeX parse error: Expected 'EOF', got '}' at position 211: … wg.Done() }̲() fmt.Prin…testObj = new TestObj(); $testObj->Hello();")
fmt.Println(“2 back”)
if err != nil {
fmt.Println(err)
}
//theEngine.DestroyContext(context2)
fmt.Println(“2 done”)
wg.Done()
}()
wg.Wait()
after := time.Now()
fmt.Println(after.Sub(before))
上一篇:http://www.xdy666.com/
下一篇:http://www.xitong5s.com/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值