比特币源码分析(五) - 初始化之SetupEnvironment() 和 noui_connect()

主程序的入口函数main()在bitcoind.cpp文件中:

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

    // Connect bitcoind signal handlers
    noui_connect();

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

这篇文章主要分析下 SetupEnvironment() 和 noui_connect() 源码。

SetupEnvironment()方法

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) {//如果是32位系统,就将内存池数目设置为1个,默认是2个,避免导致使用过多的虚拟地址空间
        mallopt(M_ARENA_MAX, 1);
    }
#endif
    // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale
    // may be invalid, in which case the "C" locale is used as fallback.
#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);//本地化文件路径设置
}

内存池设置
glibc库默认会创建2个arena,而这会对32为系统造成虚拟地址空间不足的问题,所以判断若是32位系统,就将内存池数目设置为1个。mallopt函数是用来控制malloc内存分配时的行为的(具体请参考http://man7.org/linux/man-pages/man3/mallopt.3.html),而M_ARENA_MAX参数是指最多能创建的arena数,一个arena是指malloc在分配内存时的一个内存池。

区域设置
locale()方法是设置系统区域,即国家或地区设置,决定程序所使用的当前语言编码、日期格式、数字格式及其它与区域有关的设置,locale将影响到程序中字符串处理(wchar_t如何输出、strftime()的格式等)。

本地化文件路径设置
boost::filesystem::path::imbue()方法是文件系统的本地化设置。主要涉及宽字符(Wide char)和多字节(Multi bytes)之间的转换问题。

noui_connect()方法

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

该方法实现无界面情况下连接bitcoind信息处理程序,ThreadSafeMessageBox,ThreadSafeQuestion,InitMessage这三个变量声明在src/ui_interface.h文件中,都是boost::signals2::signal类型。这里涉及到Boost信号/槽机制。看下槽函数noui_ThreadSafeMessageBox:

static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
{
    bool fSecure = style & CClientUIInterface::SECURE;
    style &= ~CClientUIInterface::SECURE;

    std::string strCaption;
    // Check for usage of predefined caption
    switch (style) {
    case CClientUIInterface::MSG_ERROR:
        strCaption += _("Error");
        break;
    case CClientUIInterface::MSG_WARNING:
        strCaption += _("Warning");
        break;
    case CClientUIInterface::MSG_INFORMATION:
        strCaption += _("Information");
        break;
    default:
        strCaption += caption; // Use supplied caption (can be empty)
    }

    if (!fSecure)
        LogPrintf("%s: %s\n", strCaption, message);
    fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str());
    return false;
}

该函数将相应的消息输出到日志中,同时也输出到标准异常输出设备中。

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