2010-11-27 second day lecture by JohnBull
Signal:
先执行signal,再执行alarm
signalaction, sigsuspend()
Thread:
X86访问内存是以cache行为单位
推荐《深入理解计算机系统》,当代计算机组成原理
信号安全和线程安全是不一样的,信号安全更难(同一线程内)
pthread_cleanup_push pthread_cleanup_pop 解决cancel thread时泄露的问题
推迟cancel模式(取消点后才cancel,默认)、异步cancel模式
确定取消点:pthread_testcancel(void); 引入cancel是为了提高性能
return不执行cleanup过程,推荐用pthread_exit();
高密度、高性能要求、内核的用c语言写
锁:
mutex lockf
同一线程会阻塞 自己不挡自己
解锁 不区分
可打开别人的锁 解锁 区分
线程环,锁链。loop.c
信号量:man 3 sem_init
sem_post(+1) sem_wait(-1) 需要够减,不够减就等着
否则只能用丑陋的忙等算法 或者 mutex + pthread_cond_wait不忙等
pthread_cond_broadcast 池类算法 惊群效应
多线程还是多进程?
多线程,前提是共享L2,多核。L2 cache不共享的smp的话是多进程。
syslog-ng用单线程也是完全有道理的,cpu再慢也慢不过硬盘(无脑拷贝型程序)
很多时候我们不要自己把自己逼到绝路上
Linux的网路协议栈,不能充分利用多处理器
OpenBSD安全的没法使了 推荐Linux和FreeBSD
pthread_mutexattr_setpshared 置为真 则fork后同一mutex为共享的引用
平时用的是PTHREAD_MUTEX_NORMAL,而不是DEFAULT
置为PTHREAD_MUTEX_ERRORCHECK,一切可疑的加减锁都会报错,包括解别人的锁
PTHREAD_MUTEX_RECURSIVE,实现自己不挡自己挡别人,记着自己加了几次,加几次必须解几次
个人建议不许同时用线程和信号
pthread_sigmask多线程使用,POSIX规定在对多线程下调用进程sigmask结果未定义
线程间发信号 pthread_kill
posix定义,在线程中使用fork,新进程中只有执行fork的那个线程,其他线程不存在
过早优化乃万恶之源 确定瓶颈之前即为过早 正确即可
高级I/O:
非阻塞I/O
select 多路复用 有疙瘩 linux/bsd有歧义 timeval上 bsd是const 不改
要想安全的用就用pselect
poll 与 ppoll
epoll: man 7 epoll question and answers
沿触发:来数据后读了一次就不告诉你了,无论是否读光。除非有新的来
ONESHOT:一次性 直到EPOLL_CTL_MOD设置 线程池用
aio:
吞吐率、响应速度 矛盾 aio就是向响应速度方向优化
aio_read aio_error aio_return
IPC:
文件锁:内存操作,无须磁盘io
管道: 流式操作规程 匿名管道需要fork的父子进程
XSI(SYSV)IPC: 消息队列、共享内存、信号量数组
消息队列:一进程读 一进程写 proc/sys/kernel/msgmax消息大小 msgmnb消息数量
少量结构体传递 报式操作规程 可以挑着收 -sizeof(long)
信号量数组:多个信号量元素可以原子
共享内存: mmap不可移植 xsi共享内存可以
apue end
内核调优:
mmap 对多进程的频繁写入的效果好 拉下读性能
mlock 禁止换出 fsync -> buffer buffer大 表示大量写操作 cache大表示读
电梯算法:NOOP无操作 CFQ公平 Deadline尽量保证实时性 as重载
vmstat top, ltrace strace, stap,opprofile
rhca 内核优化 就是要通过理解内核工作原理来切入
MTU -> Jumbo frame up 30% 打开矩阵