<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Zeromq on codedump notes</title>
    <link>https://www.codedump.info/zh/tags/zeromq/</link>
    <description>Recent content in Zeromq on codedump notes</description>
    <generator>Hugo</generator>
    <language>zh</language>
    <lastBuildDate>Sat, 09 Feb 2019 20:10:13 +0800</lastBuildDate>
    <atom:link href="https://www.codedump.info/zh/tags/zeromq/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>zeromq所谓的“无锁消息队列”</title>
      <link>https://www.codedump.info/zh/post/20190209-zeromq-lockfree-queue/</link>
      <pubDate>Sat, 09 Feb 2019 20:10:13 +0800</pubDate>
      <guid>https://www.codedump.info/zh/post/20190209-zeromq-lockfree-queue/</guid>
      <description>&lt;p&gt;本文基于zeromq 4.3.0版本，分析其无锁消息队列的实现。&lt;/p&gt;&#xA;&lt;h1 class=&#34;heading&#34; id=&#34;概述&#34;&gt;&#xA;  概述&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e6%a6%82%e8%bf%b0&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;zeromq这个网络库，有以下几个亮点：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;从以往的面向TCP流的网络开发，变成了面向消息的开发。应用层关注的是什么类型的消息，库本身解决网络收发、断线重连等问题。&lt;/li&gt;&#xA;&lt;li&gt;将这些消息的传输模式封装成几个模式，应用开发者只需要关注自己的业务符合什么模式，采用搭积木的方式就能构建起应用服务。&lt;/li&gt;&#xA;&lt;li&gt;内部实现无锁消息队列用于对象间通信，类似actor模式。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 class=&#34;heading&#34; id=&#34;基本架构&#34;&gt;&#xA;  基本架构&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#%e5%9f%ba%e6%9c%ac%e6%9e%b6%e6%9e%84&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;zeromq内部运行着多个io线程，每个io线程内部有以下两个核心组件：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;poller：即针对epoll、select等事件轮询器的封装。&lt;/li&gt;&#xA;&lt;li&gt;mailbox：负责接收消息的消息邮箱。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;可以简单理解IO线程做的事情是：内部通过一个poller，监听着各种事件，其中包括针对IO线程的mailbox的消息，以及绑定在该IO线程上的IO对象的消息。&lt;/p&gt;&#xA;&lt;p&gt;即这是一个per-thread-per-loop的线程设计，线程之间的通信通过消息邮箱来进行。&lt;/p&gt;&#xA;&lt;p&gt;除了io线程之外，io对象也有mailbox，即如果想与某个IO对象通信也是通过该mailbox进行。由于消息邮箱是zeromq中的重要组成部分，下面将专门分析zeromq是如何实现的。&lt;/p&gt;&#xA;&lt;p&gt;所有需要收发消息的对象都继承自object_t：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;class &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;object_t&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;public:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;object_t&lt;/span&gt; (zmq::&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;ctx_t&lt;/span&gt; *ctx_, &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;uint32_t&lt;/span&gt; tid_);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;process_command&lt;/span&gt; (zmq::&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;command_t&lt;/span&gt; &amp;amp;cmd_);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;private:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  zmq::&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;ctx_t&lt;/span&gt; *ctx;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;//  Context provides access to the global state.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;uint32_t&lt;/span&gt; tid;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;//  Thread ID of the thread the object belongs to.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#666;font-weight:bold;font-style:italic&#34;&gt;send_command&lt;/span&gt; (&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;command_t&lt;/span&gt; &amp;amp;cmd_);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;而IO对象之间的命令通过command_t结构体来定义：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;command_t&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#888;font-style:italic&#34;&gt;//  Object to process the command.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#888;font-style:italic&#34;&gt;&lt;/span&gt;  zmq::&lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;object_t&lt;/span&gt; *destination;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;enum&lt;/span&gt; &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;type_t&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } type;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;font-weight:bold;text-decoration:underline&#34;&gt;union&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } args;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以看到，zeromq实现对象间相互通信依赖于mailbox，本文重点在分析其无锁队列的实现上。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
