比特币源码研读之三:从入口开始

上次讲了src文件夹即比特币的源码所在目录,今天从程序入口,也就是main函数开始,比特币源码有好几个可执行程序,也就有好几个程序入口,我们从最重要的一个也就是src目录下的bitcoind.cpp下的main函数开始,这里注意是bitcoind.cpp不是bitcoin.cpp,在bitcoin后面多了一个d,而bitcoin.cpp是primitive文件夹下的其他文件,里面也有一个main函数,但不是我们要找的这个。

源码如下:

int main(int argc, char* argv[])
{
    SetupEnvironment();

    // Connect bitcoind signal handlers
    noui_connect();

    return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
}


  SetupEnvironment();顾名思义,主要就是设置运行比特币节点需要的一些环境,其函数定义在util.cpp里,

源码如下:

void SetupEnvironment()
{
#ifdef HAVE_MALLOPT_ARENA_MAX
    // glibc-specific: On 32-bit systems set the number of arenas to 1.
    // By default, since glibc 2.10, the C library will create up to two heap
    // arenas per core. This is known to cause excessive virtual address space
    // usage in our usage. Work around it by setting the maximum number of
    // arenas to 1.
    if (sizeof(void*) == 4) {
        mallopt(M_ARENA_MAX, 1);
    }
#endif
    // On most POSIX (POSIX是Unix的标准)systems (e.g. Linux, but not BSD(BSD (Berkeley Software Distribution,伯克利软件套件)是Unix的衍生系统)) the environment's locale
    // may be invalid, in which case the "C" locale is used as fallback.//可能会不合法,在这种情况下,“C”语言环境用作后备。
#if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
    try {
        std::locale(""); // Raises a runtime error if current locale is invalid//如果当前区域设置无效,则引发运行时错误
    } catch (const std::runtime_error&) {
        setenv("LC_ALL", "C", 1);
    }
#endif
    // The path locale is lazy initialized and to avoid deinitialization errors
    // in multithreading environments, it is set explicitly by the main thread.
    // A dummy locale is used to extract the internal default locale, used by
    // fs::path, which is then used to explicitly imbue the path.
    std::locale loc = fs::path::imbue(std::locale::classic());
    fs::path::imbue(loc);
}

它其实干了三件事:

第一部分:

if (sizeof(void*) == 4) {
        mallopt(M_ARENA_MAX, 1);
    }

这个地方是内存分配区设置,从代码看它先通过sizeof(void*)==4判断当前系统是否为32位,如果是就让系统按CPU进行自动设置,目的是为了防止32位操作系统中虚拟地址空间过渡使用。其实已经和区块链的实现无关了。这里不深究,知道它就是程序中的控制内存分配就行,不会影响后面的理解。

第二部分:

    try {

        std::locale(""); // Raises a runtime error if current locale is invalid(//如果当前区域设置无效,则引发运行时错误)

    } catch (const std::runtime_error&) {

        setenv("LC_ALL", "C", 1);

    }

本地化设置,系统区域设置,就是国家或地区设置,将决定程序所使用的当前语言编码、日期格式、数字格式及其它与区域有关的设置,依然不重要,知道有这么个东西就行。

第三部分:

 std::locale loc = fs::path::imbue(std::locale::classic());
    fs::path::imbue(loc);

本地化文件路径设置,具体实现不用管,和区块链的实现一点关系都没有。


现在我们回到main函数里面下一句是noui_connect();

这个的定义在noui.cpp里

源码如下:

void noui_connect()
{
    // Connect bitcoind signal handlers
    uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);
    uiInterface.ThreadSafeQuestion.connect(noui_ThreadSafeQuestion);
    uiInterface.InitMessage.connect(noui_InitMessage);
}

顾名思义,noui,没有UI(user interface用户界面)该文件实现是无操作界面的,noui_connect就是无界面情况下的信息连接,具体实现和区块链没关系,就跳过。


回到main函数里面下一句是

return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);

也就是执行AppInit(argc, argv)如果为真就返回EXIT_SUCCESS,为假就返回EXIT_FAILURE

AppInit(argc, argv)是应用程序初始化,也就是整个比特币后台进程真正开始运行的入口。

所以重要的东西就是这个AppInit(argc, argv)里到底写了什么:

我们下篇文章讲。

 

 

你可能感兴趣的:(区块链,比特币)