life's a struggle.
2016-04-20
2016-04-18
2016-04-18
API
1 | int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); |
select
nfds 3个描述符集合中最大的描述符+1,用来减少select遍历次数
readfds 监听对应描述符集合的读就绪(包括end-of-file即tcp断开)
writefds 监听对应描述符集合的写就绪
exceptfds 监听对应描述符集合的异常
对比epoll
:
通过不同的set来监听对应事件,增加了数据拷贝量
通过修改传入的set,来返回对应IO就绪套接字(所以对于应用层代码来说,还需要额外保存下原set)
通过4个辅助宏来管理描述符,和判断哪个描述符上IO就绪
BUGS:
- 在linux中,select可能返回对应的描述符读就绪,但实际读失败。可能原因有,数据到达但校验失败被丢弃或者被惊醒
优缺点
优点
- 跨平台,普遍支持
缺点
描述符大小有限制(也就限制了数量),因为内部采用bitmap(固定数组)实现,只能预分配固定大小的
描述符必须小于
FD_SETSIZE
效率较低
从api上看,监听套接字的多个事件时,需要更多的拷贝,因为select是通过set来区分事件的
每次调用都需要从应用层拷贝描述符集合到内核
每次调用返回,都需要遍历整个描述符集合比较
要点
fd_set实现(/usr/include/sys/select.h
)
描述符采用整数数组实现,通过bitmap来存储对应描述符
FD_SETSIZE
默认为1024/usr/include/bits/typesizes.h #define __FD_SETSIZE 1024
源码分析
/usr/include/sys/select.h
1 | /* The fd_set member is required to be an array of longs. */ |
/usr/include/bits/select.h
1 |
|
2016-04-14
2016-04-14
是什么?
为什么需要?
如何查看?
如何优化?
1 | net.ipv4.tcp_tw_reuse = 1 |
2016-04-13
安装VBoxGuestAdditions
配置sudo
visudo wallace ALL=(ALL) NOPASSWD: ALL
安装epel(http://www.cyberciti.biz/faq/installing-rhel-epel-repo-on-centos-redhat-7-x/)
yum install epel-release
添加组
yum install libuser lgroup -M wallace vboxsf
配置环境变量
vi /etc/profile
配置系统语言
echo LANG=en_US.UTF-8 >/etc/locale.conf
配置启动时间
vi /boot/grub2/grub.cfg set timeout=1
2016-04-12
产生的必要条件
- 互斥
- 请求与保持
- 不被剥夺
循环等待
一直等待请求额外互斥资源
可能发生的场景
在函数嵌套调用中,多次请求同一资源
不同线程中,以不同的顺序请求多个资源,而其中某个资源不足
调试与诊断方法
ps
查看进程PID,状态,阻塞原因gdb attach
到目标进程保存现场,防止后续调试破环
generate-core-file
查看所有线程的调用栈
thread apply all bt
切换到相应线程
thread NUM
查看相应互斥量,持有情况(
pthread_mutex_t.__owner
)print MUTEX
预防
- 打破产生死锁的4个必要条件中的任何一个
利用RAII手段,确保stack mutex离开作用域时被解锁(
MutexGuard, std::lock_guard
)异常结束(throw)
分支跳出(break, continue, return)
意外退出点(exit)
2016-04-08
选项
-dCHARS
CHARS
前面不能有空格M
处理
#define
指令D(常用)
Like M except in two respects: it does not include the predefined macros, and it outputs both the #define directives and the result of preprocessing.
Both kinds of output go to the standard output file.I
Output #include directives in addition to the result of preprocessing.
参考
2016-04-07
区别
占用空间
char(M)占用空间固定,M[0,255]个字符,具体占用字节与编码相关
varchar(M[0,65535])占用空间不固定,因为首部占用1或2B来记录长度M+1(
M<256
),占用M+2(255<M<65536
)
关于空格
在存储字符串到char中时,会填充空格至相应长度
取出char类型值时,若
sql_mode
没有设置PAD_CHAR_TO_FULL_LENGTH
,则会去除尾部空格所以导致插入带空格的字符串,取出时却不带有空格!
varchar会存储空格和保留空格,不会转换!
参考
2016-04-05
配置(/etc/redis.conf)
1 | requirepass foobared # 设置密码 |
命令
启动redis
redis-server /etc/redis.conf
根据pattern删除key
redis-cli KEYS "prefix:*" | xargs redis-cli DEL
命令返回值
1 | typedef struct redisReply { |
状态(
#define REDIS_REPLY_STATUS 5
),str
=> valueSET
=> “OK”PING
=> “PONG”
错误(
#define REDIS_REPLY_ERROR 6
),str
=> value整数(
#define REDIS_REPLY_INTEGER 3
),integer
=> value一些整数操作命令,如
INCR
返回增加后的键值字符串(
#define REDIS_REPLY_STRING 1
),str
=> value当请求一个字符串类型键的键值时,若每个键不存在,则返回特殊值
nil(#define REDIS_REPLY_NIL 4)
字符串数组(
#define REDIS_REPLY_ARRAY 2
),str
=> value,element
=> next
备份与恢复
SAVE
同步保存数据到磁盘文件中
dbfilename dump.rdb dir /var/lib/redis/
BGSAVE
异步保存
CONFIG get dir
恢复数据(dir由
/etc/redis.conf
中定义)
Server端处理客户端socket
Redis 通过监听一个 TCP 端口或者 Unix socket 的方式来接收来自客户端的连接,当一个连接建立后,Redis 内部会进行以下一些操作:
- 首先,客户端 socket 会被设置为非阻塞模式,因为 Redis 在网络事件处理上采用的是非阻塞多路复用模型。
- 然后为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法
- 然后创建一个可读的文件事件用于监听这个客户端 socket 的数据发送