ZeroMQ 源码阅读

一、创建context

zmq_ctx_new()

context 干嘛用的?

context 是用于管理全局状态的,例如sockets, io_thread, repear等。下面是zmq内部结构白皮书的解释:

To prevent this problem libzmq has no global variables. Instead, user of the library is responsible for creating the global state explicitly. Object containing the global state is called ‘context’. While from the users perspective context looks more or less like a pool of I/O threads to be used with your sockets, from libzmq’s perspective it’s just an object to store any global state that we happen to need. For example, the list of available inproc endpoints is stored in the context. The list of sockets that have been closed but still linger in the memory because of unsent messages is held by context. Etc.

Context is implemented as class ctx_t.

ctx_t内主要有这几类线程:

  • Application thread,这是应用主线程。

  • 若干 I/O threads,可以没有I/O线程,也可以有多个。

  • repear thread,用于关闭和清理 sockets。

    使用回收线程 repear 是为了:

    You can close TCP socket, the call returns immediately, even if there’s pending outbound data to be sent to the peer later on.

  • term thread,用于销毁。

一个context内可以有多个sockets:

// Sockets belonging to this context. We need the list so that
// we can notify the sockets when zmq_ctx_term() is called.
// The sockets will return ETERM then.
typedef array_t <socket_base_t> sockets_t;
sockets_t sockets;

每个线程都有自己的邮箱,所以用一个数组来管理这些邮箱:

// Array of pointers to mailboxes for both application and I/O threads.
uint32_t slot_count;
i_mailbox **slots;

总而言之,ctx_t就是负责管理 sockets 和 threads的。

 二、创建socket

void *zmq_socket (void *ctx_, int type_)
{
    ...
   zmq::ctx_t *ctx = (zmq::ctx_t *) ctx_;
   zmq::socket_base_t *s = ctx->create_socket (type_);
   return (void *) s;
}

可见,实际是调用了ctx->create_socket的方法,跳到ctx.cpp去看看。

逻辑还是比较简单的,大致分成两步:

  1. 创建各路工作线程。I/O threads, repear thread, term thread(应该是自身线程,无须创建),并且注册每个线程的邮箱(上文提到,用一个vector记录每个object的mailbox)。
  2. 创建socket,并注册其邮箱。
    socket_base_t *s = socket_base_t::create (type_, this, slot, sid);

你可能感兴趣的:(源码,分布式,消息队列,library,zeromq)