-
Archives
- January 2012
- December 2011
- August 2011
- July 2011
- June 2011
- April 2011
- March 2011
- February 2011
- January 2011
- December 2010
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
-
Meta
Category Archives: 系统编程
binary hacks 记录
6、 静态库和共享库 静态库的编写通常如下: cc -c -o foo.o goo.c cc -c -o bar.o bar.c ar ruv libfoo.a foo.o bar.o 查看库的内容: ar tv libfoo.a 连接使用:cc -o baz baz.o -lfoo
Posted in 系统编程
3 Comments
epoll 的 et 和 lt
本文来自:Linux那些破事儿之我的高性能 但凡对epoll有一点点了解的人,都听说过epoll有两种工作模式,即ET(Edge Trigger)和LT(Level Trigger)模式。这两种工作模式的中文翻译分别是边沿触发和电平触发,还可以称为事件触发和条件触发。我倒是觉得后者的翻译更能清楚的描述这两种工作模式的特点和差别。 当epoll工作在LT模式下,只要其监控的I/O句柄具备调用者所要捕获的条件——一般是可读或可写——就会通知给调用者。如果调用者不理会这个通知,它将一直通知下去,直到这个状态发生变化。当采用多进程模式(后面会详细介绍)编写服务器软件时,根据系统任务调度特性,采用LT模式可以使得所有连接均匀的分布于每个用于处理网络请求的进程。有汽车驾驶经验的童鞋可以将LT模式理解为驾驶自动档的汽车,只要设置好你感兴趣的I/O句柄和事件类型,在具备条件的时候epoll就会通知你,只需要做相关的处理就可以了,非常轻松惬意,代价就是稍微多出的那么一点点油耗。 当epoll工作在ET模式下,情况有些变得复杂了。原因就是这种基于事件的通知是事件发生后,只会产生一次通知。如果你不去理会它,它也不会再理会你,直到下一次事件发生。这会导致一个严重的后果就是当一个编写不够良好的程序,在获得事件通知后并没有将缓冲区的数据全部读取干净,epoll也不会有任何通知,没有读取到数据可能永远都不会被读取,或者使得那部分数据超时。另外,ET模式只允许非阻塞式I/O,这就进一步加剧了上述问题的恶化。解决的方法就是反复读取缓冲区,直到返回错误。所以,如果说LT模式是自动挡,那么ET模式就是手动挡,所有情况都得自己处理,处理不好就可能熄火,好处就是经济实惠。另外,ET模式在多进程服务器软件中,会导致连接在处理进程之间的不均匀分布,不过也只是相对的,当发现问题严重时,可适当暂停某个进程做接受新连接的处理。 答案就是:如果要发送数据,大多数直接调用send或wirte就可以了,直到他们返回EAGAIN错误,才需要将它们交给epoll去监控。一旦epoll_wait返回某个被监控的I/O句柄可写,则应该立即利用epoll_ctl将它删除,直到下次再出现EAGAIN错误。不过虽然说起来简单,但是真正到具体的操作还是比较麻烦。要完整可靠的发送数据:必须记录每次实际发送的数据量来统计剩余量;当发生EAGAIN错误后,必须将剩余的数据保存在一个地方,一般放在epoll_event结构的data字段中即可;当epoll通知可写后,将剩余数据发送出去;但是当遇到压力较大时,可能在发送剩余数据的时候还会发生EAGAIN错误,必须始终记录剩余数据才行。
Posted in 系统编程
Leave a comment
TCP/IP 基本概念
1、 阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有 区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回 值 <0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况 下认为连接是正常的,继续接收。只是阻塞模式下recv会阻塞着接收数据,非阻塞模式下如果没有数据会返回,不会阻塞着读,因此需要 循环读取
connect 的超时
connect 默认好像没法控制超时。但是可以将 connect 的描述符设置为非阻塞,然后用 select 来控制的办法。 先 socket,设置为非阻塞,然后调用 connect,如果出错的 errno 是 EINPROGRESS,则调用 select 在描述符上等待可读和可写。 http://sue602.blog.163.com/blog/static/314953072010102422418685/ http://blog.csdn.net/chensichensi/archive/2010/01/28/5264481.aspx
Posted in 系统编程
Leave a comment
rsync 原理
http://www.samba.org/rsync/how-rsync-works.html http://rsync.samba.org/tech_report/ http://wangyuanzju.blog.163.com/blog/static/130292010101252632998/
Posted in 系统编程
Leave a comment
多进程多线程的选择
这篇文章来自这里: http://software.intel.com/zh-cn/blogs/2010/07/20/400004478/ 关于多进程和多线程,教科书上最经典的一句话是“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试基本上够了,但如果在工作中遇到类似的选择问题,那就没有这么简单了,选的不好,会让你深受其害。 经常在网络上看到有的XDJM问“多进程好还是多线程好?”、“Linux下用多进程还是多线程?”等等期望一劳永逸的问题,我只能说:没有最好,只有更好。根据实际情况来判断,哪个更加合适就是哪个好。
Posted in 系统编程
Leave a comment
Nginx memcached 模块
Nginx 提供了一个 memcached 模块,使得能够从 memcached 中获取某些信息,而不仅仅是从本地文件了,这个特性要结合 upstream 模块;upstream 使得 Nginx 可以将接收到的请求转发给后端,然后它从后端读取并返回给客户端。 在代码实现上,upstream 算是一个比较复杂的模块,除去静态内容,Nginx 绝大多数情况下可能处理的都是动态产生的内容,比如 PHP,理清原理对熟悉 Nginx 有些帮助。 这个功能应该由 ngx_http_memcached_pass 中的 ngx_http_memcached_handler 驱动;这个 handler 函数使用 ngx_http_upstream_create 来初始化一个 upstream;upstream 中字段繁多,其中的 pipe 是 NULL。还要注册很多函数指针,譬如创建请求、处理头部之类的。然后进入 ngx_http_upstream_init 开始处理。 接下来的调用流程是 ngx_http_upstream_init -> ngx_http_upstream_init_request 调用 upstream 的 … Continue reading
Nginx 整体结构
Nginx 可以是单进程,多进程或者多进程中的每个进程是多进程几种模式; 但是每个进程中多线程的情况似乎文档没说。 普通情况下是一个主进程多个工作进程,如果设置 master_process 为 off,则 nginx 只有一个进程,这个选项不要在生产环境中使用。 默认情况下这个选项是 on 的,此时是一个主多个 worker 进程。 配置文件的解析在 ngx_init_cycle 函数中,它被 main 调用。 如果只有一个进程,则进入 ngx_single_process_cycle;否则进入 ngx_master_process_cycle。 ngx_master_process_cycle 中将利用 ngx_start_worker_processes 产生多个工作进程;而主进程位于 for(;;) 循环中。利用 sigsuspend 来等待外来的信号响应。 每个工作进程被产生出来以后会进入 ngx_worker_process_cycle 函数。 如果工作进程中有线程,则线程产生出来后调用 ngx_worker_thread_cycle 函数,这些线程会 sleep 在 ngx_cond_wait 函数中等待唤醒,醒来后处理 … Continue reading
Nginx 接收连接的过程
ngx_event_process_init 会根据最大的连接数目 N 来初始化 free_connections,还会初始化 N 个 write_event 和 N 个 read_event,每个连接的 read 事件则指向对应的 read_event,write 则指向 write_event,这些 read_event 和 write_event 的 handler 是 ngx_http_request_handler;而反过来,这些 read_event 和 write_event 的 data 则指向被分配的 connection; 然后用 ngx_get_connection 函数从监听的描述符的可用的连接中选出一个 ngx_connection_t(看 ngx_connection.c 中的 ngx_get_connection 函数),添加一个可读事件以及处理函数 ngx_event_accept。 … Continue reading
Nginx 事件通知与定时器
Nginx 支持多种事件通知机制,从 select 到 epoll,kquene 之类。 src/event/modules 目录中定义了各个机制的具体实现,在编译时只会有一个被编译进去,这取决于选择哪个事件机制了。 从上层看,它们都被抽象为 ngx_event_module_t 类型。 在 ngx_event.c 中的 ngx_event_process_init 会对选择的事件机制初始化,对 epoll 而言,实际就是调用的 ngx_epoll_init 来对 epoll 做初始化。 并会加上 flag:NGX_USE_CLEAR_EVENT。 对于 UDP,ngx_event_t 的写事件的 ready 总是准备好的(ready = 1)。 而 ngx_event_t 的 active 则表明事件是否是活跃的:参考 ngx_epoll_add_event 中添加事件的处理方式,这涉及到是 EPOLL_CTL_MOD 还是 … Continue reading
J+-Tree: A New Index Structure in Main Memory
Hua Luan1,2, Xiaoyong Du1,2, Shan Wang1,2, Yongzhi Ni1,2, and Qiming Chen3 1 School of Information, Renmin University of China, Beijing, China 2 Key Laboratory of Data Engineering and Knowledge Engineering, Renmin University of China, MOE, Beijing, China 3 HP Labs … Continue reading
Posted in 系统编程
Comments Off
socket 中的几个读写函数
ssize_t send(int s, const void *buf, size_t len, int flags); ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); ssize_t sendmsg(int s, const struct msghdr *msg, int flags); 用于发送消息到另外一个 socket 上。 send () … Continue reading
Posted in 系统编程
Leave a comment
memcached分析
1、可以选择使用TCP还是UDP; 2、多线程程序; 刚开始的时候listen_conn会被初始化; 有几个地址,listen_conn就会有几个元素,上的每个都会进行listen? memcached使用了libevent,事件的处理函数被设置为event_handler;在这个函数中将会调用drive_machine进行事件的处理。drive_machine处在事件循环之中,包括进行accept操作,进入conn_listening状态则进行accept。但只有主线程才进入这个状态。 每个线程会使用pipe形成管道。 setup_thread函数会加入管道读端可读时的事件。 libevent的逻辑就是设置你感兴趣的事件,然后写一个状态循环。 在accept之后, 如果是多线程则调用dispatch_conn_new塞入一个CQ_ITEM到一个线程的队列中,并往管道中写一个字节;塞入管道之后thread_libevent_process会调用(由于事先在setup_thread注册过),将从队列中取出一个CQ_ITEM生成conn。 如果不是多线程则调用conn_new,生成一个conn。
Posted in 系统编程
Leave a comment
显示 epoll ET 和 LT 区别的例子
一个简单的例子,显示 ET 和 LT 的区别; LT 即是水平触发,只要还有数据便会通知你; ET 是边界触发,一旦你得到通知,可是你并没有读完,则你不会被再通知,除非状态发生改变,比如像下面例子中子进程不断往管道中灌数据,就可以是一种状态改变。如果要采用 ET 模式,需要一直 read/write 直到出错为止。 特别要主意 man 手册中的话,使用 ET 时一定要使用非阻塞式。比如你期望读到 36 字节,可是你只读到 32 字节,那么你不得不再次尝试,可是在阻塞情况下如果数据没有到达,你就卡住了没法处理别的请求。 http://www.wangafu.net/~nickm/libevent-book/ http://blog.csdn.net/sparkliang/archive/2009/11/05/4770655.aspx libevent在异步socket中的使用 http://blog.csdn.net/liutaoxwl/archive/2008/09/22/2962143.aspx
Posted in 系统编程
Leave a comment