The Eventlet is used in OpenStack to implement concurrency.
First, use Eventlet. Greenpool to manage green threads
If L3-agent has 8 green threads open to process router messages
def _process_routers_loop (self): pool = Eventlet. Greenpool (size=8) while True: pool.spawn_n (self._process_router_update)
The second is to create a green thread directly from the process that creates the message in oslo.messaging
Eventlet.spawn ()
So what are the processes that the green threads have gone through?
When using Greenlet to create a new object, it is created using the call Green_new (Tp_new), which is initialized using Green_init (__init__). When you create an object with Green_new, the parent of this Greenlet object is set to the current Greenlet.
Static pyobject* green_new (Pytypeobject *type, Pyobject *args, Pyobject *kwds) {pyobject* o = pybaseobject_type.tp_new ( Type, ts_empty_tuple, ts_empty_dict); if (o! = NULL) {if (! STATE_OK) {py_decref (o); return NULL;} Py_incref (ts_current);((P ygreenlet*) o)->parent = ts_current;} return o;}
The Run function information is set at initialization, Self->run_info = Nrun.
When referencing the Greenlet library, the main greenlet is referenced, and this is a library that is transparent to the user, so when using the Greenlet library, there will be a run of main Greenlet after the Greenlet run that was explicitly created to continue execution.
When referencing the module, the Initmodulename function is called to initialize, there is a corresponding Initgreenlet function for the Greenlet library, Green_create_main is called to create the main Greenlet
Staticpygreenlet* Green_create_main (void) {Pygreenlet*Gmain; Pyobject* Dict =pythreadstate_getdict ();/*Create the main greenlet for this thread*/Gmain= (pygreenlet*) pytype_genericalloc (&pygreenlet_type,0);Gmain->stack_start = (Char*)1; Gmain->stack_stop = (Char*) -1; Gmain->run_info =dict; Py_incref (DICT); returnGmain;}
The following three actions are performed when calling Gr.switch to complete the switchover.
- Save thread State, EIP
- C-Stack switching, assembly implementation
- Restore the target thread state, that is, the jump execution location
Static pyobject* green_new (Pytypeobject *type, Pyobject *args, Pyobject *kwds) {pyobject* o = pybaseobject_type.tp_new ( Type, ts_empty_tuple, ts_empty_dict); if (o! = NULL) {if (! STATE_OK) {py_decref (o); return NULL;} Py_incref (ts_current);((P ygreenlet*) o)->parent = ts_current;} return o;}
Using Eventlet in OpenStack