C语言中的define语法

在看apache的mod_ssl的时候,发现有这么一种写法:

#define SSL_CMD_ALL(name, args, desc) \
        AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
                       NULL, RSRC_CONF|OR_AUTHCFG, desc),

其中的 ## 不知道啥意思了,网上查了一下,是这样子的:

#define Conn(x,y) x##y
#define ToChar(x) #@x
#define ToString(x) #x
#define Dec(x,y) (x-y)

x##y表示什么?表示x连接y,举例说:
int n = Conn(123,456);   结果就是n=123456;
char* str = Conn("asdf", "adf")结果就是 str = "asdfadf";
怎么样,很神奇吧

再来看#@x,其实就是给x加上单引号,结果返回是一个const char。举例说:
char a = ToChar(1);结果就是a=’1′;
做个越界试验char a = ToChar(123);结果是a=’3′;
但是如果你的参数超过四个字符,编译器就给给你报错了!error C2015: too many characters in constant   :P

最后看看#x,估计你也明白了,他是给x加双引号
char* str = ToString(123132);就成了str="123132";

那么#define Dec(x,y) (x-y) , 在后面使用了圆括号,是说让define有返回值

mysql 主从配置中的server-id的作用

server-id做什么用的,你知道吗?

1、 mysql的同步的数据中是包含server-id的,用于标识该语句最初是从哪个server写入的,所以server-id一定要有的

2、 每一个同步中的slave在master上都对应一个master线程,该线程就是通过slave的server-id来标识的;每个slave在master端最多有一个master线程,如果两个slave的server-id 相同,则后一个连接成功时,前一个将被踢掉。 这里至少有这么一种考虑:
   slave主动连接master之后,如果slave上面执行了slave stop;则连接断开,但是master上对应的线程并没有退出;当slave start之后,master不能再创建一个线程而保留原来的线程,那样同步就可能有问题;

3、 在mysql做主主同步时,多个主需要构成一个环状,但是同步的时候有要保证一条数据不会陷入死循环,这里就是靠server-id来实现的

PHP源码阅读点滴

下面讨论的PHP都是5.1.5版本的。

1. PHP源码文件 Zend/zend_globals.h 中的_zend_executor_globals定义了执行时全局的hash表:
    /* symbol table cache */
    HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
    HashTable **symtable_cache_limit;
    HashTable **symtable_cache_ptr;

    HashTable *active_symbol_table;
    HashTable symbol_table;     /* main symbol table */

    HashTable included_files;   /* files already included */
    HashTable *function_table;  /* function symbol table */
    HashTable *class_table;     /* class table */                    
    HashTable *zend_constants;  /* constants table */
    HashTable *in_autoload;

    HashTable regular_list;
    HashTable persistent_list;

    HashTable *ini_directives;

这里面只列了hash表类型的字段,从中可以看出: 函数、类、常量、头文件等都是存储为hash表的。

2. PHP源码文件 Zend/zend_globals.h 中的下列结构应该说明declare 关键字可以声明的内容都有哪些,似乎目前只有ticks

typedef struct _zend_declarables {
    zval ticks;
} zend_declarables;

3. hash表数据结构,Zend/zend_hash.h 文件中:

typedef struct _hashtable {
    uint nTableSize;
    uint nTableMask;
    uint nNumOfElements;
    ulong nNextFreeElement;
    Bucket *pInternalPointer;   /* Used for element traversal */
    Bucket *pListHead;
    Bucket *pListTail;
    Bucket **arBuckets;
    dtor_func_t pDestructor;
    zend_bool persistent;
    unsigned char nApplyCount;
    zend_bool bApplyProtection;
#if ZEND_DEBUG
    int inconsistent;
#endif
} HashTable;

4. PHP内部的Hash函数, Zend/zend_hash.h中:
static inline ulong zend_inline_hash_func(char *arKey, uint nKeyLength)
{
    register ulong hash = 5381;

    /* variant with the hash unrolled eight times */
    for (; nKeyLength >= 8; nKeyLength -= 8) {
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
        hash = ((hash << 5) + hash) + *arKey++;
    }
    switch (nKeyLength) {
        case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */
        case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */
        case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */
        case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */
        case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */
        case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough… */
        case 1: hash = ((hash << 5) + hash) + *arKey++; break;
        case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
    }
    return hash;
}

5. hash表查找函数:

/* Returns SUCCESS if found and FAILURE if not. The pointer to the
 * data is returned in pData. The reason is that there’s no reason
 * someone using the hash table might not want to have NULL data
 */
ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData)
{
    ulong h;
    uint nIndex;
    Bucket *p;
       
    IS_CONSISTENT(ht);

    h = zend_inline_hash_func(arKey, nKeyLength);  
    nIndex = h & ht->nTableMask;
    p = ht->arBuckets[nIndex];
    while (p != NULL) { 
        if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
            if (!memcmp(p->arKey, arKey, nKeyLength)) {
                *pData = p->pData;
                return SUCCESS;
            }
        }
        p = p->pNext; 
    }        
    return FAILURE;
}    

这里面:    
    h = zend_inline_hash_func(arKey, nKeyLength);  
    nIndex = h & ht->nTableMask;
就可以定位到具体的
Bucket了,特别是这个按位与的操作,就可以知道Bucket的数量了,怎么算呢?

6. 文件Zend/zend_globals_macros.h中定义了EG:
# define EG(v) (executor_globals.v)

EG 就是executor_globals的意思,比如EG(ini_directives) 就是:
executor_globals.ini_directives

从上面的结构体executor_globals就可以知道这是在做什么了

7. Zend/zend_ini.h 中定义了ini变量的结构体:

struct _zend_ini_entry {
    int module_number;
    int modifiable;
    char *name;
    uint name_length;
    ZEND_INI_MH((*on_modify));
    void *mh_arg1;
    void *mh_arg2;
    void *mh_arg3;

    char *value;
    uint value_length;

    char *orig_value;
    uint orig_value_length;
    int modified;

    void (*displayer)(zend_ini_entry *ini_entry, int type);
};

8. ini_set 函数是在源码中是通过函数zend_alter_ini_entry来实现的,其中的modifytype参数值为:PHP_INI_USER

 

关于Linux的crontab 与 sar

我们一般用root使用crontab -e写crontab的时候,是写在 /var/spool/cron/root  文件中的,通过strace crontab -l 可以看到, 对于每个用户来讲,都可以有自己的crontab,对应文件为:
/var/spool/cron/{username}

如果目录 /var/spool/cron 的权限为700, 则非root用户将不被允许使用cron了

另外, cron在执行的时候,不仅扫描 /var/spool/cron 目录,还会扫描 /etc/crontab 文件和 /etc/cron* 的相关目录和文件。

如: /etc/cron.daily/logrotate 是配置系统日志的滚动的,每天一次

对于sar命令,是属于sysstat包中的,通过配置文件: /etc/cron.d/sysstat

———————————————————
# run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib/sa/sa1 1 1
# generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib/sa/sa2 -A
———————————————————

使得10分钟获取一次系统信息

通过配置文件: /etc/sysconfig/sysstat

—————————————————
# How long to keep log files (days), maximum is a month
HISTORY=7
—————————————————-

来配置保存数据多长时间,最长1个月,因为历史数据默认保存在目录: /var/log/sa/ 中,每天一个文件,文件名的格式为 sa + day-of-month , 如:
-rw-r–r– 1 root root 382704 Sep  1 23:50 sa01
-rw-r–r– 1 root root 382704 Sep  2 23:50 sa02
-rw-r–r– 1 root root 236624 Sep  3 14:20 sa03
-rw-r–r– 1 root root 382704 Aug 26 23:50 sa26

另外,这些文件不是以文本格式存放的,不能直接查看,可以通过命令:

sar -f /var/log/sa/sa02 200

-f 选项默认是当天的文件
200 是查看多少条,默认(还没看)

======================================================

主要是这个工具可以查看历史负载,所以才看了一下。

sar 10分钟一次,每天产生370K的文件,如果改为1分钟1次,则每天也才3.7M的文件,对于查看服务器的状态已经查不多了

无言的感怀

无言的感怀

作者 花未眠

人生有多少故事

真实的令人心碎

人生有多少记忆

总是置于心的高地

有多少梦可以重来

有多少人值得等待

又有多少感慨可以

化成许多无言的感怀

评论:
何处找回青春年少,何日登临儿时楼台,寄言风清月白,谁堪白露秋凉?一曲古琴流水融入沉箫,一杯浊酒相伴病魂悠悠……

命运的安排总是那样的无奈,很难把荣辱沉浮面对,叹往昔不可再来,喜风雨之后,依然有别样的精彩!

有多少是非能说明白,有多少收获值得欣慰,有多少失误可以修改,有多少情结谁来解开?有多少爱,痴心为谁,有多少怨,怎生掩埋?人间是舞台,人生多无奈,偏爱上层楼,叹风清月白?
 

磁盘相关


Linux上磁盘的名字有/dev/hdx  和 /dev/sdx 的,其中:
/dev/hd[a-t] : 表示 IDE/ATA 设备
/dev/sd[a-t] :  表示 SCSI 或 SATA 设备

关于磁盘的一些指标和报价可以参考一些设备官方网站:

网上折扣店:http://discountechnology.com/
简介: 主要销售企业级硬件,包括存储设备、网络设备、显示器等, 你可以到这里看一下各种新型磁盘的报价,路由器的报价等等。当然你也可以查看一些设备的详细参数。

希捷官方: http://www.seagate.com/
(如果遇到死循环,你可以修改一下你的浏览器的accept-language 为english)

关于smartctl 的使用参考:
http://smartmontools.sourceforge.net/

硬盘的种类:

IDE
SCSI
SATA
SSD

它们的区别还需要花时间去学习

一种js的回调的写法

url:  http://phpor.net/render_js.php?callback=cb
返回:
(function(){ if(‘cb’ && cb) { var call = cb; var json ={…}; call(json); } })();

一般来讲,写为:
cb({…});
就够了,这样的话,cb为空或者该函数不存在就会出现js错误

或者,写成如下:
if(‘cb’ && cb) { var call = cb; var json ={…}; call(json); }

不觉得这种方式和第一种有什么区别。