浅谈几种服务器端模型,python回调函数
分类:高并发

Python回调函数用法实例详细明白,python回调函数实例

本文实例叙述了Python回调函数用法。分享给大家供大家仿照效法。具体深入分析如下:

豆蔻年华、百度百科上对回调函数的解释:

回调函数便是三个经过函数指针调用的函数。借使您把函数的指针(地址卡塔尔作为参数字传送递给另四个函数,当以此指针被用为调用它所针没错函数时,大家就说那是回调函数。回调函数不是由该函数的落到实处方平昔调用,而是在一定的风云或条件爆发时由其余的一方调用的,用于对该事件或标准举行响应。

二、什么是回调:

软件模块之间连接存在着自然的接口,从调用方式上,能够把他们分成三类:同步调用、回调养异步调用。同步调用是朝气蓬勃种拥塞式调用,调用方要等待对方奉行达成才回去,它是朝气蓬勃种单向调用;回调是意气风发种双向调用格局,也正是说,被调用方在接口被调用时也会调用对方的接口;异步调用是后生可畏种相仿音讯或事件的机制,但是它的调用方向正巧相反,接口的劳动在吸收接纳某种消息或爆发某种事件时,会继续努力通报客户方(即调用顾客方的接口)。回调弄收拾异步调用的涉嫌十一分严密,平时大家运用回调来贯彻异步新闻的挂号,通过异步调用来落到实处消息的通报。同步调用是三者当中最轻易易行的,而回调又反复是异步调用的底子,因而,上边我们重视研究回调机制在区别软件构造中的完毕。

三、多少个小例子:

#call.py 
import called 
def callback(): 
  print "in callback" 
def main(): 
  #called.test() 
  called.test_call(callback) 
  print "in call.py" 
main() 
#called.py 
''''' 
def test(): 
  print "in called.py test()" 
''' 
def test_call(p_call): 
  print "in called.py test_call()" 
  p_call() 
[email protected]:~/test/python$ python call.py 
in called.py test_call() 
in callback 
in call.py 
[email protected]:~/test/python$

网络搜到的多少个面向对象达成的例子:

当您要加盟回调(Callback)效率的时候,代码往往会偏重于回调的兑现而小意思作者了。贰个消灭措施就是落到实处一个通用的功底类来解决回调的须要,然后再来达成您为某些事件(Event)所绑定(Binding)的方式(Method)。

代码如下:

class CallbackBase: 
  def __init__(self): 
 self.__callbackMap = {} 
 for k in (getattr(self, x) for x in dir(self)): 
   if hasattr(k, "bind_to_event"): 
 self.__callbackMap.setdefault(k.bind_to_event, []).append(k) 
   elif hasattr(k, "bind_to_event_list"): 
 for j in k.bind_to_event_list: 
   self.__callbackMap.setdefault(j, []).append(k) 
  ## staticmethod is only used to create a namespace 
  @staticmethod 
  def callback(event): 
 def f(g, ev = event): 
   g.bind_to_event = ev 
   return g 
 return f 
  @staticmethod 
  def callbacklist(eventlist): 
 def f(g, evl = eventlist): 
   g.bind_to_event_list = evl 
   return g 
 return f 
  def dispatch(self, event): 
 l = self.__callbackMap[event] 
 f = lambda *args, **kargs:  
   map(lambda x: x(*args, **kargs), l) 
 return f 
## Sample 
class MyClass(CallbackBase): 
  EVENT1 = 1 
  EVENT2 = 2 
  @CallbackBase.callback(EVENT1) 
  def handler1(self, param = None): 
 print "handler1 with param: %s" % str(param) 
 return None 
  @CallbackBase.callbacklist([EVENT1, EVENT2]) 
  def handler2(self, param = None): 
 print "handler2 with param: %s" % str(param) 
 return None 
  def run(self, event, param = None): 
 self.dispatch(event)(param) 
if __name__ == "__main__": 
  a = MyClass() 
  a.run(MyClass.EVENT1, 'mandarina') 
  a.run(MyClass.EVENT2, 'naranja') 

此间有一个类,它有八个事件(EVENT1和EVENT2)和三个管理函数(handler)。第叁个管理函数handler1注册了EVENT1,而第三个处理函数handler2当EVENT1可能EVENT2发生的时候都会推行(即注册了方方面面包车型客车平地风波)。

运作函数(run)在MyClass的主循环中,它会将相应的风浪派送(dispatch)出去。那(这里指dispatch函数)会重回叁个函数,咱们得以把富有需求传给这么些函数的参数列表传给它。那些函数运转截止会回到二个列表(list),列表中是具备的重回值。

兴许,使用Metaclass可以落到实处的越来越高贵一些呢。

盼望本文所述对大家的Python程序设计具备利于。

本文实例呈报了Python回调函数用法。分享给我们供我们参照他事他说加以考查。具体解析如下: 生龙活虎、百度百...

python回调函数用法实例解析,python回调函数

正文实例呈报了python回调函数用法。分享给大家供大家参谋。具体剖析如下:

软件模块之间延续存在着自然的接口,从调用方式上,能够把她们分成三类:同步调用、回调护诊治异步调用。同步调用是生龙活虎种梗塞式调用,调用方要等待对方实行完结才回到,它是风流洒脱种单向调用;回调是少年老成种双向调用格局,也正是说,被调用方在接口被调用时也会调用对方的接口;异步调用是大器晚成种恍若音讯或事件的机制,然而它 的调用方向赶巧相反,接口的劳动在汲取某种新闻或发生某种事件时,会继续努力打招呼客商方(即调用客商方的接口)。回调治将养异步调用的涉及极度严密,日常大家应用 回调来得以完成异步音讯的挂号,通过异步调用来贯彻消息的通报。同步调用是三者个中最简易的,而回调又反复是异步调用的底蕴,由此,这里大家珍视斟酌回调机制 在差异软件构造中的完成。

#call.py
import called
def callback():
  print "in callback"
def main():
  #called.test()
  called.test_call(callback)
  print "in call.py" 
main()

#called.py
'''''
def test():
  print "in called.py test()"
'''
def test_call(p_call):
  print "in called.py test_call()"
  p_call()

[email protected]:~/test/python$ python call.py
in called.py test_call()
in callback
in call.py
[email protected]:~/test/python$

指望本文所述对我们的Python程序设计具备助于。

本文实例汇报了python回调函数用法。分享给我们供大家参照他事他说加以考察。具体深入分析如下: 软件模块之间总...

引言:前边意气风发章简介了有关epoll 的选拔办法,那生龙活虎章介绍一下一个轻巧易行的反应堆模型,未有贯彻超机会制的保管。最关键的是要介绍一下有关异步事件反应堆的规划方式。

概念

Vuex 相近 Redux 的状态微机,用来处理Vue的保有组件状态。

反应堆的模子图在上一巴索戈以看看,可是丰盛是盗来的一张图,twisted 的反应堆。今日给面生这一个有个其余相爱的人介绍一下基于 epoll 的反应堆,进度看似于libevent.

干什么选择Vuex?

当您准备开采大型单页应用(SPA),会并发多少个视图组件信赖同叁个情景,来自区别视图的行事须求转移同叁个动静。
遇上上述情况时候,你就相应考虑接收Vuex了,它能把组件的分享状态抽出出来,当作三个大局单例方式张开管理。那样不管您在何地改革状态,都会通报使用该情状的构件做出相应修改。

反应堆能够提供多少个操作:

图例

图片 1

vuex

vue组件触发(dispatch卡塔尔国事件给actions(动作卡塔尔国,actions提交动作给mutations,mutations引起state状态改动,转而vue组件上渲染改动

(0)成立二个反应堆:

主干配备

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//创建Store实例
const store = new Vuex.Store({
  // 存储状态值
  state: {
    ...
  },
  // 状态值的改变方法,操作状态值
  // 提交mutations是更改Vuex状态的唯一方法
  mutations: {
    ...
  },
  // 在store中定义getters(可以认为是store的计算属性)。Getters接收state作为其第一个函数
  getters: {
    ...
  },
  actions: { 
    ...
  }
})
// 要改变状态值只能通过提交mutations来完成
/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
  // 将store实例注入到根组件下的所有子组件中
  store
  // 子组件通过this.$store来方位store
})
mc_event_base_t * mc_base_new(void) ;

骨干概念

再次回到二个操作句柄.  

state

Vuex 使用 单纯性状态树 —— 是的,用三个对象就隐含了全部的运用层级状态。至此它便作为一个『唯生机勃勃数据源』而留存。那也意味,每种应用将独自富含四个store 实例。单黄金年代状态树让大家能够一向地坚持住任黄金年代特定的景象有个别,在调节和测量检验的长河中也能随随意便地获取任何当前使用状态的快速照相。
单状态树和模块化并不冲突 —— 在后头的章节里我们议和谈何将情形和意况更改事件布满到种种子模块中。

(1)为某三个内需监听的文书陈诉符插手回调函数,并登记事件类型。

在 Vue 组件中赢得 Vuex 状态

那么我们怎么样在 Vue 组件中显得状态吧?由于 Vuex 的情景存储是响应式的,从 store 实例中读取状态最容易易行的不二诀窍正是在估测计算属性中回到有个别状态:

// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}
//如果在一个vue组件中应该是:$store.state.count  $store指代的就是vuex

每当 store.state.count 变化的时候, 都会另行求取总括属性,並且触发更新相关联的 DOM。
只是,这种形式造成组件依赖的大局状态单例。在模块化的营造系统中,在种种须要利用 state 的零器件中供给频仍地导入,况且在测验组件时索要效法状态。
Vuex 通过 store 选项,提供了意气风发种体制将气象从根组件『注入』到每一个子零器件中(需调用 Vue.use(Vuex卡塔尔(قطر‎):

const app = new Vue({
  el: '#app',
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

通过在根实例中登记 store 选项,该 store 实例会注入到根组件下的全部子组件中,且子组件能透过 this.$store 访谈到。让我们立异下 Counter 的贯彻:

const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}
int mc_event_set( mc_event_t *ev , short revent , int fd , mc_ev_callback callback , void *args )  ;
    /*
     * Initialize a event , add callback and event type
     * if the event exists , this function will change the mode of this event
     * and fd 
     */

mapState 扶植函数

当三个构件必要获得多个状态时候,将这个情状都宣示为总结属性会轻微重复和冗余。为了消除这么些主题素材,我们能够动用 mapState 协理函数扶持我们生成总计属性,令你少按四次键:

// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
  computed: mapState({
    // 箭头函数可使代码更简练
    count: state => state.count,
    // 传字符串参数 'count' 等同于 `state => state.count`
    countAlias: 'count',
    // 为了能够使用 `this` 获取局部状态,必须使用常规函数
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
}

 这里的 revent 由宏定义为几系列型:

对象实行运算符

mapState函数重临的是三个对象。我们什么样将它与一些总结属性混合使用呢?平日,我们供给利用八个工具函数将四个对象合併为三个,以使大家得以将最后目的传给 computed属性。可是自从有了指标开展运算符(现居于 ECMASCript 议事原案 stage-3 阶段),大家能够大幅地简化写法:

computed: {
  localComputed () { /* ... */ },
  // 使用对象展开运算符(扩展运算符)将此对象混入到外部对象中
  ...mapState({
    // ...
  })
}

  

Getters

有的时候大家须求从 store 中的 state 中派生出一些景况,比如对列表举行过滤并计数:
假如有多少个零件须要用到此属性,大家照旧复制这么些函数,恐怕收取到贰个共享函数然后在多处导入它 —— 无论哪一类方法都不是超漂亮好。
Vuex 允许大家在 store 中定义『getters』(能够以为是 store 的精兵简政属性)。Getters 接收 state 作为其首先个参数:

//store.js
const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
//理解为store的计算属性,对state中的数据进行处理
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

Getters 会揭露为 store.getters 对象:

//components
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
#define MC_EV_READ     0x0001
#define MC_EV_WRITE    0x0002
#define MC_EV_SIGNAL   0x0004
#define MC_EV_TIMEOUT  0x0008
#define MC_EV_LISTEN   0x0010

mapGetters 帮助函数

mapGetters 扶持函数仅仅是将 store 中的 getters 映射到一些总结属性:

import { mapGetters } from 'vuex'
export default {
  computed: {
  // 使用对象展开运算符将 getters 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount'
    ])
  }
}

相应的操作还行 | 运算来并多少个须要监听的轩然大波类型。

Mutations

改善 Vuex 的 store 中的状态的独一情势是提交 mutation。Vuex 中的 mutations 极其左近于事件:每种 mutation 都有一个字符串的 事件类型 (typeState of Qatar和 一个 回调函数 (handler卡塔尔(قطر‎。这一个回调函数就是大家实际进行状态校勘的地点,而且它会经受 state 作为第一个参数:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 变更状态
      state.count++
    }
  }
})

您不可能从来调用多个 mutation handler。那个选项更疑似事件注册:“当接触贰个门类为 increment 的 mutation 时,调用此函数。”要提示三个 mutation handler,你须求以相应的 type 调用 store.commit 方法:

store.commit('increment')

事件类型定义如下:

付给载荷(Payload)

您能够向 store.commit 传入额外的参数,即 mutation 的 载荷(payload):

// mutations.js
mutations: {
  increment (state, n) {
    state.count += n
  }
}
//event
store.commit('increment', 10)

在大超多意况下,载荷应该是三个目的,那样能够蕴含八个字段何况记录的 mutation 会更易读:

// ...
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
store.commit('increment', {
  amount: 10
})
typedef struct mc_event_s
{

      struct mc_event_s   *next    ;


      struct mc_event_s   *prev    ;

     unsigned int min_heap_index  ;

     int ev_fd      ;   // file des of event
     short revent   ;   // event type

     struct timeval  ev_timeval   ; // event timeout time 
     mc_ev_callback callback ;// callback of this event 
     void  *args                  ;
     int ev_flags                 ;

     mc_event_base_t    *base     ;
}mc_event_t ;

目的风格的交由方式

交给 mutation 的另风姿罗曼蒂克种方式是从来运用含有 type 属性的目的:

store.commit({
  type: 'increment',
  amount: 10
})

当使用对象风格的交付情势,整个对象都看成载荷传给 mutation 函数,因而handler 保持不改变:

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}

事件协会自个儿后边解释。 

动用常量取代 Mutation 事件类型

利用常量代替 mutation 事件类型在种种 Flux 达成中是特别不感到奇的情势。那样能够使 linter 之类的工具发挥成效,同一时候把那么些常量放在单独的文本中得以让您的代码同盟者对总体 app 包涵的 mutation 不言而谕:

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
  state: { ... },
  mutations: {
    // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
    [SOME_MUTATION] (state) {
      // mutate state
    }
  }
})

(2)将索要监听的同一时间风度翩翩度起头化的平地风波参加反应堆。

mutation 必需是一块函数

一条至关心珍视要的法规正是要铭记在心 mutation 必得是协同函数。为何?请参考上面的例子:

mutations: {
  someMutation (state) {
    api.callAsyncMethod(() => {
      state.count++
    })
  }
}

前段时间虚构,大家正在 debug 二个 app 並且观看 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools 都急需捕捉到前生龙活虎状态和后风流倜傥景观的快速照相。不过,在地点的事例中 mutation 中的异步函数中的回调让那不也许形成:因为当 mutation 触发的时候,回调函数还不曾被调用,devtools 不清楚哪些时候回调函数实际上被调用 —— 实质上别的在回调函数中张开的的情状的转移都是不可追踪的。

int mc_event_post( mc_event_t *ev , mc_event_base_t * base ) ;
    /*
     * Post this event to event_base 
     * struct base has two queue , active queue and added queue
     * this function will post event to added queue , but not in active queue
     */

在组件中付出 Mutations

你能够在组件中采用 this.$store.commit('xxx'卡塔尔 提交 mutation,只怕选取mapMutations 支持函数将零构件中的 methods 映射为 store.commit 调用(要求在根节点注入 store)。

import { mapMutations } from 'vuex'
export default {
  // ...
  methods: {
    ...mapMutations([
      'increment' // 映射 this.increment() 为 this.$store.commit('increment')
    ]),
    ...mapMutations({
      add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
    })
  }
}

将刚刚登记了风浪类型和回调函数的平地风波到场 base, 就要其视作一个反应堆。

Actions

Action 相符于 mutation,不相同在于:

Action 提交的是 mutation,实际不是直接更动状态。
Action 能够包含自由异步操作。

让大家来注册多个精简的 action:

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    },
//es6解构赋值的用法
  //increment ({ commit }) {
  //  commit('increment')
  //}
  }
})

Action 函数选用多少个与 store 实例拥有相似方式和质量的 context 对象,由此你能够调用 context.commit 提交一个 mutation,只怕经过 context.state 和 context.getters 来赢得 state 和 getters。

(3)最终提供了三个 dispatch 函数,反应堆最初循环,等待事件的发生。假设对应的 fd 上的平地风波时有产生,调用相应的回调函数。由第一步注册。

分发 Action

Action 通过 store.dispatch 方法触发:

 store.dispatch('increment')

乍一眼看上去认为节外生枝,大家一向分发 mutation 岂不更有益?实际上并不是那样,还记得 mutation 必需一齐实践这几个界定么?Action 就不受限定!大家得以在 action 内部进行异步操作:

关键在于actions能够异步操作,而mutations必得协同实施

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}

Actions 支持相似的载重形式和目的情势张开分发:

// 以载荷形式分发
store.dispatch('incrementAsync', {
  amount: 10
})
// 以对象形式分发
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})
int mc_dispatch( mc_event_base_t * base ) ;
    /*
     * start loop 
     * and dispatch event by 
     * mc_event_loop
     */

在组件中散发 Action

您在组件中央银行使 this.$store.dispatch('xxx'State of Qatar 分发 action,或然使用 mapActions 帮忙函数将构件的 methods 映射为 store.dispatch 调用(要求先在根节点注入 store):

import { mapActions } from 'vuex'
export default {
  methods: {
    ...mapActions([
      'increment' // 映射 this.increment() 为 this.$store.dispatch('increment')
    ]),
    ...mapActions({
      add: 'increment' // 映射 this.add() 为 this.$store.dispatch('increment')
    })
  }
}

反应堆扶植在循环进度中,通过相应的回调函数再登记事件,类似于热参加,热移除。

组合 Actions

Action 通常是异步的,那么哪些晓得 action 曾几何时截至呢?更器重的是,我们怎样工夫结合多个action,以处理越发扑朔迷离的异步流程?
率先,你需求领会 store.dispatch 能够拍卖被触发的action的回调函数再次回到的Promise,况且store.dispatch依旧重临Promise:

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

这段时间您能够:

store.dispatch('actionA').then(() => {
  // ...
})

在此外三个 action 中也得以:

actions: {
  actionB ({ dispatch, commit }) {
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}

提起底,若是我们使用 async / await 那些 JavaScript 将要赶到的新特色,我们能够像那样组合 action:

// 假设 getData() 和 getOtherData() 返回的是 Promise
actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}

二个 store.dispatch 在差异模块中得以触发四个 action 函数。在此种地方下,独有当全部触发函数完结后,重回的 Promise 才会施行。

福寿无疆格局超轻便,便是在首先个事件的回调函数上调用 mc_event_set(卡塔尔然后注册。再投入 base.

base 的布局如下 :

typedef struct mc_event_base_s
{
    void         *  added_list      ;
    void         *  active_list     ;
    unsigned int    event_num       ;
    unsigned int    event_active_num;

    /*
     *mc_minheap        minheap         ;
     */
    int             epoll_fd        ;  //for epoll only 
    int             ev_base_stop    ;
    int             magic           ;
    struct timeval  event_time      ;   
}mc_event_base_t ;

让大家来看叁个简便的 demo

/*_____________________test bellow ______________________*/
#define mc_sock_fd  int


#define DEFAULT_NET AF_INET
#define DEFAULT_DATA_GRAM   SOCK_STREAM
#define DEFAULT_PORT        (1115)
#define DEFAULT_BACKLOG     (200)

/* simple connection */
struct _connection
{
    int fd            ;
    mc_event_t  read  ;
    mc_event_t  write ;
    char buf[1024]    ;
    mc_event_base_t * base ;
};
void setreuseaddr( mc_sock_fd fd )
{
    int yes = 1 ;
    setsockopt( fd , SOL_SOCKET , SO_REUSEADDR , &yes , sizeof(int) );
}
int mc_socket()
{
    int retsock = socket(DEFAULT_NET,DEFAULT_DATA_GRAM,0) ;
    if( retsock < 0  )
    {
        /* we should add some debug information here
        fprintf(LOGPATH,"socket errorn");
        */
        return -1 ;
    }
    return retsock ;
}       

int mc_bind(mc_sock_fd listenfd )
{
    struct sockaddr_in serveraddr ;
    bzero(&serveraddr,sizeof(serveraddr));

    serveraddr.sin_family = AF_INET ;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(DEFAULT_PORT);
    return bind(listenfd,(struct sockaddr *)&serveraddr , sizeof(serveraddr ));
}

int mc_isten(mc_sock_fd listenfd)
{
    return listen(listenfd,DEFAULT_BACKLOG);
}



void handler_accept( int fd , short revent , void *args )
{
    struct sockaddr_in in_addr ;
    size_t in_len ;
    int s   ;
    int done = 0 ;
    struct _connection * lc = (struct _connection *)args ;

    in_len = sizeof( in_addr );
    mc_setnonblocking(fd) ;
    while( !done )
    {
        s = accept( fd , (struct sockaddr *)&in_addr , &in_len );
        if( s == -1 )
        {
            if( (errno == EAGAIN )|| (errno == EWOULDBLOCK ) )
            {
                break;
            }
            else
            {
                perror("accept");
                break;
            }
        }
        if( s == 0 )
        {
            fprintf(stderr,"Accept a connection on %d n",fd );
        }
        done = 1 ;
    }
        mc_setnonblocking(s) ;
        lc->fd = s ;
        mc_event_set( &(lc->read) , MC_EV_READ , lc->fd , handler_read , lc );


        mc_event_set( &(lc->write) , MC_EV_WRITE , lc->fd , handler_write , lc );
        mc_event_post( &(lc->write) , lc->base );


}
void handler_read( int fd , short revent , void *args )
{
    mc_setnonblocking(fd) ;
    struct _connection * lc ;
    lc  = (struct _connection *)args ;
    read( fd , lc->buf , 1024 );
    mc_event_set( &(lc->write) , MC_EV_WRITE , lc->fd , handler_write , lc );
}

void handler_write( int fd , short revent , void *args )
{
    mc_setnonblocking(fd) ;
    struct _connection * lc ;
    lc  = (struct _connection *)args ;
    write( fd , lc->buf , 1024 );
    mc_event_set( &(lc->read) , MC_EV_READ , lc->fd , handler_read , lc );
}

void cab( int fd , short revent , void *args )
{
    mc_setnonblocking(fd) ;
    char buf[1024] = "xx00xx00xx00xx00n";
    write(fd,buf,1024);
}
int main()
{
    mc_event_t mev ;
    mc_event_base_t  *base = mc_base_new() ;
    struct _connection lc ;
    lc.base = base ;

    int sockfd = mc_socket() ;
    mc_bind(sockfd);
    mc_isten(sockfd);

    mc_event_set( &(lc.read) , MC_EV_READ , sockfd , handler_accept , &lc );
    mc_event_post( &(lc.read) , base );
    mc_dispatch(base);
    return 0;
}

  

第后生可畏:封装的多少个套接口操作未有杜撰错误处理,作为简单的实例。

概念了贰个 connection 构造,用于表示每二个驾临的连天,这里的 struct _connection 中包涵读写事件和四个缓冲区,还大概有针对性反应堆的指针和对应注册的fd

做事进程如下:(聚焦看  main函数)

(1)创制一个反应堆。

(2)实例化叁个 connection

(3)创造套接口,bind,listen 老生常谈,这里就十分的少说了

(4)将以此监听套接口注册相应的回调函数,这里我们报了名的是 handler_accept(卡塔尔国 函数,回调函数类型都以  void *XXX(  int  , short , void *) ;

       当监听套接口发生可读事件时,第一次我们以为是对应的监听套接口获得了新的总是,所以,第叁遍调用的时候一向调用注册了的回调函数 handler_accept().

在handler_accept(State of Qatar函数中,我们为那些接二连三的读写事件添加了相应的回调函数,并把连接描述符(不是监听描述符)注册到那几个上。后一次这一个套接口可读的时候调用handler_read(State of Qatar,可写的时候调用handler_write(卡塔尔. 若是须求退换状态或转移回调函数,只要求二个状态机大概其他方法来规定必要的回调函数是哪三个,在大家的handler_write() 和 handler_read(卡塔尔中能够改正回调函数,代码所示。

 

PS:注意一点的是大家的风浪是叁个实例,不管是在connection布局中大概本身定义,都供给不断的向操作系统申请空间,如果应用对象池也许connection池的艺术,能够减掉服务器的载荷。

小结:反应堆格局最基本的操作便是:注册事件(为必要监听的fd参预回调函数)----->将事件参与反应堆------>起首事件循环------>事件时有产生,调用回调函数。

异步操作的精华便是在这里间,并非一只的守候每二个风云。下生龙活虎章解说这一个反应堆的贯彻,越来越带感咯.

本文由10bet手机官网发布于高并发,转载请注明出处:浅谈几种服务器端模型,python回调函数

上一篇:安装基于系统认证的vsftp服务 下一篇:Python简单实现子网掩码转换的方法,python实现将英文单词表示的数字转换成阿拉伯数字的方法
猜你喜欢
热门排行
精彩图文