(一)nginx-初始化流程

(一)nginx-初始化流程


nginx代码结构复杂,但是再复杂的程序都是可认知的,让我们从开始,一步一步来。

int ngx_cdecl main(int argc, char *const *argv)

ngx_cdecl是一个空的宏。仅仅是为了平台移植的方便。

ngx_int_t         i;
 ngx_log_t        *log;
 ngx_cycle_t      *cycle, init_cycle;
 ngx_core_conf_t  *ccf;
 ngx_debug_init();//应该是初始化debug版本,但在linux中,此函数定义为空

 if (ngx_strerror_init() != NGX_OK) {
       return 1;
 }

ng_sterror_init 错误初始化函数。进入此函数。

ngx_int_t
ngx_strerror_init(void)
{
char       *msg;
u_char     *p;
size_t      len;
ngx_err_t   err;

/*
 * ngx_strerror() is not ready to work at this stage, therefore,
 * malloc() is used and possible errors are logged using strerror().
 */

len = NGX_SYS_NERR * sizeof(ngx_str_t);
//NGX_SYS_NERR是操作系统识别的错误个数,
//在centos7上是133,编译出的ngin是135,可能nginx是为了做一点空间的冗余。

ngx_sys_errlist = malloc(len);//为错误信息数组分配空间
if (ngx_sys_errlist == NULL) {
    goto failed;
}
//ngx_sys_errlist是一个全局的错误数组,类型为ngx_str_t。

for (err = 0; err < NGX_SYS_NERR; err++) {
    msg = strerror(err);//错误内容
    len = ngx_strlen(msg);//错误信息长度

    p = malloc(len);
    if (p == NULL) {
        goto failed;
    }

    ngx_memcpy(p, msg, len);
    ngx_sys_errlist[err].len = len;
    ngx_sys_errlist[err].data = p;
}
//上面这段很清晰了,完成错误数组初始化。
return NGX_OK;

failed:

err = errno;
ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err));

return NGX_ERROR;
}

解析命令行参数部分。把参数保存在全局变量中。

if (ngx_get_options(argc, argv) != NGX_OK) {
    return 1;
}

如果命令行中有-h -v -V,则ngx_show_version会为1,在console上会打印help信息。

if (ngx_show_version) {
...
}

/* TODO */ ngx_max_sockets = -1;

ngx_time_init();

ngx_time_init中的ngx_time_update中有个ngx_trylock函数。

#define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
#define ngx_unlock(lock)    *(lock) = 0

其中ngx_atomic_cmp_set定义如下:

#define ngx_atomic_cmp_set(lock, old, set)                                    \
__sync_bool_compare_and_swap(lock, old, set)

#define ngx_atomic_fetch_add(value, add)                                      \
__sync_fetch_and_add(value, add)

里面用到了gcc提供的原子操作。效率如何没做具体的性能测试,可再查下文献。


gcc原子操作简单测试例子。

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <unistd.h>
#include <sys/types.h>

int val = 0;
int mu = 0;

#define ngx_atomic_cmp_set(lock, old, set)                                    \
    __sync_bool_compare_and_swap(lock, old, set)

#define ngx_atomic_fetch_add(value, add)                                      \
    __sync_fetch_and_add(value, add)

#define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
#define ngx_unlock(lock)    *(lock) = 0

void* fun1(void *)
{
    while (1) {
        if (!ngx_trylock(&mu)) {
            return NULL;
        }
        val += 1;
        ngx_unlock(&mu);

        printf("fun1: %d\n", val);
        sleep(1);
    }
}

void* fun2(void *)
{
    while (1) {
        if (!ngx_trylock(&mu)) {
            return NULL;
        }
        val += 1;
        ngx_unlock(&mu);

        printf("fun2: %d\n", val);
        sleep(1);
    }
}

int main()
{
    pthread_t p1;
    pthread_t p2;

    pthread_create(&p1, NULL, fun1, NULL);
    pthread_create(&p2, NULL, fun2, NULL);

    pthread_join(p1, NULL);
    pthread_join(p2, NULL);

    return 0;
}

正则表达式初始化操作

#if (NGX_PCRE)
    ngx_regex_init();
#endif

里面是给两个回调函数赋值,分配释放空间。下面说下其中用到的ngx_palloc

void *
ngx_palloc(ngx_pool_t *pool, size_t size)
{
    u_char      *m;
    ngx_pool_t  *p;

    if (size <= pool->max) {

        p = pool->current;

        do {
            m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);

            if ((size_t) (p->d.end - m) >= size) {
                p->d.last = m + size;

                return m;
            }

            p = p->d.next;

        } while (p);

        return ngx_palloc_block(pool, size);
    }

    return ngx_palloc_large(pool, size);
}

展开篇幅太大,下一篇说下内存池的理解。

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

推荐阅读更多精彩内容