比特币源码研读之二

前一篇文章中已经完成了main函数运行过程的梳理,并且也绘制了其运行流程图,为了更清晰地记录每个过程的详细执行内容,我将从本文开始对每个过程进行说明。

在做代码分析之前,我将先把本文主要涉及的代码文件列举出来,大家可以准备好相应文件,更好地理解源码:

本文主要涉及的源码文件包括:

src/bitcond.cpp、src/util.h、src/util.cpp、src/noui.h、src/noui.cpp、ui_interface.h、ui_interface.cpp

一、设置运行环境SetupEnviroment

main函数执行的第一步是通过SetupEnviroment函数实现比特币后台进程运行环境的设置,SetupEnviroment实现位于src/util.cpp中。在研读SetupEnviroment函数之前,我们有必要先说明下其所在的实现文件util.cpp的主要功能,因为该实现文件将在后续的研读中经常出现。

util.cpp其位于src目录中。util源码文件主要功能是什么呢?我们可以从其头文件util.h的最开始处找到相应的注释说明:

/**

* Server/client environment: argumenthandling, config file parsing,

* logging, thread wrappers

*/

其大意为该源文件实现了服务器/客户端运行环境的设置,包括参数处理、配置文件解析、日志打印以及线程封装等的初始化与属性设置。也可以将util看做是对比特币核心源码的通用功能的统一封装实现文件。

再次回到SetupEnviroment函数,该函数由3部分组成:

(1)内存分配区设置

此处内存分配区设置的目的是为了防止32位操作系统中虚拟地址空间过渡使用,即程序中的控制内存分配。通过sizeof(void*)==4判断当前系统是否为32位,如果是,则通过mallopt设置只有1个内存分配区,即表示系统按CPU进行自动设置。

(2)本地化设置

C/C++程序中,locale(即系统区域设置,即国家或地区设置)将决定程序所使用的当前语言编码、日期格式、数字格式及其它与区域有关的设置,locale设置的正确与否将影响到程序中字符串处理(wchar_t如何输出、strftime()的格式等)。因此,对于每一个程序,都应该慎重处理locale设置。

具体可参见:http://blog.csdn.net/haiross/article/details/45074355

(3)本地化文件路径设置

第三部分代码主要通过boost::filesystem::path::imbue实现文件系统的本地化设置。

二、信号处理noui_connect


noui_connect函数位于noui.cpp中,从文件名noui(no ui,即无UI界面的消息连接)我们可以看出该文件实现是无操作界面的,noui_connect就是无界面情况下的信息连接!

通过分析,发现noui_connect通过信号/槽的通信方式实现子线程与主线程的消息处理功能。其处理的消息包括三类,分别是:消息弹出框信息提示消息、对用户问题询问的交互提示消息以及程序初始化过程的消息。

voidnoui_connect()

{

// Connect bitcoind signal handlers

uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);

uiInterface.ThreadSafeQuestion.connect(noui_ThreadSafeQuestion);

uiInterface.InitMessage.connect(noui_InitMessage);

}

上述代码中的uiInterfaceui_为全局变量,该变量在ui_interface.h的最后面进行了声明:

extern CClientUIInterface uiInterface;

在ui_interface.cpp文件的上方实现了其定义:

CClientUIInterface uiInterface;

我们可以看到noui_connect()实现的3行代码中,uiInterface分别调用了3个变量:

ThreadSafeMessageBox、ThreadSafeQuestion以及InitMessage

每个变量都通过connect方法调用了noui.cpp中定义的3个静态函数:

noui_ThreadSafeMessageBox、noui_ThreadSafeQuestion以及noui_InitMessage

我们来分析下上述代码的实现原理。首先来看看uiInterface调用的3个变量的类型与定义。

这3个变量位于ui_interface.h中:

/**Show message box. */

boost::signals2::signal > ThreadSafeMessageBox;

/**If possible, ask the user a question. If not, falls back toThreadSafeMessageBox(noninteractive_message, caption, style) and returns false.*/

boost::signals2::signal > ThreadSafeQuestion;

/**Progress message during initialization. */

boost::signals2::signal InitMessage;

我们可以看到这3个变量的类型均为boost::signals2::signal信号类型,同时,在signal中通过<>方式包含了程序接收到该信号时的处理方法,也就是信号接收槽,整个机制也叫信号/机制。Boost中的信号/槽机制在设计模式中对应的是观察者模式,其具体解释如下:

signals2基于Boost的另一个库signals,实现了线程安全的观察者模式。在signals2库中,观察者模式被称为信号/插槽(signals and slots),他是一种函数回调机制,一个信号关联了多个插槽,当信号发出时,所有关联它的插槽都会被调用。

许多成熟的软件系统都用到了这种信号/插槽机制(另一个常用的名称是事件处理机制:event/event handler),它可以很好地解耦一组互相协作的类,有的语言设置直接内建了对它的支持(如c#),signals2以库的形式为c++增加了这个重要的功能。

signal最重要的操作函数是插槽管理connect()函数,它吧插槽连接到信号上,相当于为信号(事件)增加了一个处理的handler。

插槽可以是任意的可调用对象,包括函数指针、函数对象、以及它们的bind表达式和function对象,signal内部使用function作为容器来保存这些可调用对象。连接时可以指定组号也可以不指定组号,当信号发生时将依据组号的排序准则依次调用插槽函数。

如果连接成功connect()将返回一个connection,表示了信号与插槽之间的连接关系,它是一个轻量级的对象,可以处理两者间的连接,如断开、重连接、或者测试连接状态。

成员函数disconnect()可以断开插槽与信号的连接,它有两种形式:传递组号将断开该组的所有插槽,传递一个插槽对象将仅断开该插槽。函数disconnect_all_slots()可以一次性断开信号的所有插槽连接。

我们再来看这3个信号/槽对象的定义,以ThreadSafeMessageBox为例:

boost::signals2::signal

(const std::string& message, const std::string& caption, unsigned int

style), boost::signals2::last_value > ThreadSafeMessageBox;

从定义中我们可以看到signal<>中包含了1个函数定义和1个类型定义:

函数定义:

bool (const std::string&message, const std::string& caption, unsigned int style)

返回类型定义:

boost::signals2::last_value

那么这个函数定义与类型定义的作用是什么呢?其实这个函数定义就是信号对应的槽,类型就是这个槽函数的返回值类型。也就是说,程序在实现该接收槽时,其参数数量、类型、返回值必须要与上述定义一致,才能正确处理对应信号!

有了这个解释,我们再来看我们本节要说明的noui_connect()函数,我们以第一行代码为例来进行代码的解读:

uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);

在第一行代码中,我们通过ThreadSafeMessageBox.connect方法确定了槽函数noui_ThreadSafeMessageBox,而这个槽函数的实现就在noui.cpp中,其函数定义如下:

static bool noui_ThreadSafeMessageBox(conststd::string& message, const std::string& caption, unsigned int style)

通过对比我们可以发现noui_ThreadSafeMessageBox其定义完全符合ThreadSafeMessageBox定义所要求的槽函数定义,在该函数中完成了对应信号的实现。通过其代码我们会发现其主要通过日志打印和文件记录方式实现相应信号的处理,以作为程序运行过程的记录。

请大家关注WX公众号:爱学习的菜菜子。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,780评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,424评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,397评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,576评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,997评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,945评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,107评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,850评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,625评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,804评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,285评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,613评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,291评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,164评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,963评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,096评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,886评论 2 278

推荐阅读更多精彩内容

  • 上一篇文章我们大致分析了一下比特币源码src文件夹的目录结构以及数据目录结构,接下来我们将进入源码的分析。本篇涉及...
    自如致知阅读 1,463评论 2 1
  • 这一节主要讲解比特币使用信号/槽通信的相关知识。 // Connect bitcoind signal handl...
    Jacky_2c9f阅读 600评论 0 0
  • 别被消费主义和别人的话绑架,做你自己,爱你所爱,坚持自己的审美观 断舍离。体重管理。宁少勿多。咖啡文化。 是时候改...
    mupuu阅读 171评论 0 0
  • 晨练 (四侧*由琪荣原创) 一 ...
    原野_3af1阅读 385评论 1 3
  • 朋友,你大学的朋友很可能就是你将来事业的一部分。他们会帮助你。但是你也应该让自己有帮助他们的实力,所以,你...
    hpnb阅读 293评论 0 0