moduo 1

Moduo: A C++ non-blocking network library for multi-threaded server in Linux.

C++ 11 features

a. functional, bind

in C++11, function declartion can be:

1
2
3
4
5
6
7
8
9
return-type func(args)
//or
auto func(args) -> return_type
// the good part of "->" is to use "decltype" to decide the return type from future.
std::function<return_type(arg1_type, arg2_type..)> ;
[](type1, type2..){} ; //lambda func, anonymous func
std::forward

std::bind() is used to assign existed variables to func parameters during compile-time, and unassigned parameters stand as placeholders, which then replace by real parameters during running-time, and return a new func. bind() can be used to bind static func, global func, class member func.

1
2
3
4
5
6
7
8
9
10
std::bind(global_func, 1.0, _2) ;
std::bind(&class:memberfunc, classPointer[this], _1);
```
### b. multi-threads synchronized primitives
Q: what is condition variable ?
A: used to block one or more threads, till been notified by another thread or overtime been wakeup. But if all threads are waiting, that's a problem, so at least for one thread, the condition variable should be true.
threadA.wait(condition_variable);
while(;;)
{
    threadB.do();    
}
threadB.notify();
threadA.do();
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
Q: what is mutex?
A: it works like a lock, to block any other thread to access special part of memory, at any time, only one thread can own the mutex. in reality, to define mutexLock class will manage lock/unlock automatically due to the constructor/destructor of the object.
### c. rvalue reference, universal reference, std::forward
Q: why need right-value reference ?
A: to use rvalue like lvalue, save object/variable copying, the detail is about move constructor. universal reference, means either rvalue reference or lvalue reference, is to declare a variable /parameter with type T&& for some deduced type T
### d. functional template, variadic arguments
basically, it's to support any type, any number of parameters in function template.
```
template<typename… Args> class tuple{} //a template class
template<typename T, typename… Args> void func(){}
/* Args :: a template type parameter pack, a list of parameters
T :: a normal template type parameter
*/
func(T, args...)
/* (...) at right of func parameters is meta operator
used to unpack "args" into separate arguments */

a simple thread / thread pool lib

take a look at: thread-pool

basically, a task queue to store all todo tasks; a thread pool, to store the worker threads, each of which takes one task from the task queue continuously till the queue empty.

racing condition happens when two threads try to take the same task simultaneously, so mutex. and all operators requrieing thread-safe should use mutex, e.g. enqueue/dequeue task
then callback functors, how each worker thread deal with the task at hand? to design function template with variadic arguments.

a simple Tcp network lib

take a look at: simpleNetwork

in server: socket() -> bind() -> listen() -> accept() –> send()/write()

in client: socket() -> connect() -> recv()/send()

a basic idea is that each connection, the server will create a new thread to handle it. But it consume server quickly.

I/O nonblocking/event-driven & multiplex

1
2
3
4
5
6
7
8
9
10
11
struct {
int fd;
short events; //events to watch, set by user
short revents; //returned events, return from system kernel
};
POLLIN | POLLPRI ; //event read
POLLOUT | POLLWRBAND ; //event write
POLLER ; //event error
POLLHUP ; //event hang up

the basic idea of multplex(Linux APIs: poll(), epoll()) is to use one single thread to listen many connections/socket/fd, once any socket is ready for I/O, the thread will execute the write/read callback.

epoll() on success, return the number of revents or 0; on error return -1

1
2
3
4
5
6
7
8
9
struct epoll_event {
__u32 events ;
union{
void* ptr, //if need to store a pointer
int fd, // if need to store socket fd
__u32 u32, // to store general 32 bit number
__u64 u64 // to store general 64 bit number
} data;
};