ArticleDirectory
- 1. The user_t object in Lua each instance has two primary data,
- 2. c ++ encapsulate the asynchronous call of the MySQL interface and register the interface to Lua
- 3. Lua sample code
- 4. Notes:
1. Future mode:
See http://www.cnblogs.com/zhiranok/archive/2011/03/26/Future_Pattern.html
The advantage of using future is that it utilizes the Asynchronous Parallel capability and ensures the serial execution of the main logic, keeping it simple.
2. Lua coroutine
Sina timyang introduction http://timyang.net/lua/lua-coroutine/
Lua coroutine creates a pseudo thread through create. The "Thread" can suspend itself through yield. By calling resume, the "Thread" can be executed from the suspended position.
3. Lua coroutine for future
Assume that the following application scenarios are available:
1. When a user logs on to the system, the user data needs to be obtained from MySQL, and then the user_t object needs to be instantiated in Lua.
2. the user logon event is triggered by C ++ and the UID parameter is passed to Lua.
3. Lua does not have a MySQL interface. It must delegate C ++ to complete MySQL operations, and the Lua state must be operated by a single thread. We expect Lua to not be blocked and load data from MySql in a single user.
Other users should be able to accept the request
Therefore, we have designed the following solutions:
1. The user_t object in Lua each instance has two primary data,
A. request_cache: when the user is not initialized, the UID request will be cached (we encapsulate the request as a function ).
B. coroutine, The coroutine tries to complete all requests in request_cache. If the coroutine is suspended as follows:
(1) The request_cache is empty and waits for a new request.
(2) It is suspended when MySQL needs to be executed and is awakened after MySQL execution is completed.
ExampleCode:
1 User_t = {}
2 User_t. _ Index = user_t
3
4 Function User_t: New ()
5 Local Funjc = Function () Print ( " Todo EXE all request in request_cache " ) End
6 Local Ret =
7 {
8 [ " Request_cache " ] = {},
9 [ " Coroutine_obj " ] = Coroutine. Create (Funjc ),
10 }
11 Setretriable (Ret, self)
12 Return RET
13 End
2. c ++ encapsulate the asynchronous call of the MySQL interface and register the interface to Lua
1. future_t is used to transmit data for Lua and C ++.
1 ClassFuture_t
2{
3 Public:
Void set_result (const string & V _) {m_result = V _;}
4StringGet_result ()Const{ReturnM_result ;}
5 Private:
6StringM_result;
7};
2. async_load_data_from_db is used to asynchronously execute MySQL operations.
1 Void Async_load_data_from_db (future_t * RET _)
2 {
3 // ! Post another thread, async EXE load data from DB
4 Thread. Post (boost: BIND (do_load_data_from_db, RET _));
5 }
6
7 Void Do_load_data_from_db (future_t * RET _)
8 {
9 // ! Todo exe SQL opertion
10 Lua_pcall ( " Resume_routine " )
11 }
Lua calls the C ++ interface async_load_data_from_db, async_load_data_from_db, requests another post thread, executes the MySQL request, assigns the request result to future, and calls the Lua's Resume function to wake up.
Lua coroutine continues execution
3. Lua sample code
1 User_t = {}
2 User_t. _ Index = user_t
3
4 Function User_t: New (UID _)
5 Local Ret =
6 {
7 [ " UID " ] = Uid _,
8 [ " Request_cache " ] = {},
9 [ " Coroutine_obj " ] = True ,
10 [ " Runing_flag " ] = True ,
11 }
12 Setretriable (Ret, self)
13
14 Local Func = Function ()
15 While True = Runing_flag
16 If 0 ==# Ret. request_cache
17 Then
18 Coroutine. Yield ()
19 Else
20 Local Todo_func = ret. request_cache [ 1 ]
21 Local TMP = {}
22 For K = 2 , # Ret. request_cache
23 Do
24 Table. insert (TMP, Ret. request_cache [k])
25 End
26 Ret. request_cache = TMP
27 Todo_func ()
28 End
29 End
30 End
31 Ret. coroutine_obj = Coroutine. Create (Func)
32 Return RET
33 End
34
35 Function User_t: Init ()
36 Local Func = Function ()
37 Local Future = future_t: New ()
38 Async_load_data_from_db (future)
39 Coroutine. Yield ()
40 Print ( " User_t: init OK " , Self. uid, future: get_result ())
41 Future: delete ()
42 End
43 Table. insert (Self. request_cache, func)
44 Coroutine. Resume (Self. coroutine_obj)
45 End
46
47 Function User_t: resume_routine ()
48 Coroutine. Resume (Self. coroutine_obj)
49 End
50
51 Local Test_user = user_t: New ( 1122334 )
52
53 Function User_login ()
54 Return Test_user: Init ()
55 End
56
57 Function Resume_routine ()
58 Return Test_user: resume_routine ()
59 End 4. Notes:
Although a Lua state is executed in serial mode, pay attention to data consistency when using Lua coroutine. For example, if a global variable is used during coroutine execution, the global variable may be modified after yield is suspended,
Therefore, coroutine is suitable for the user_t object in the example. Each user does not interfere with each other. The same user request will be serialized by a single coroutine.