代码改变世界

一、管道与FIFO

2013-10-05 16:38  O_NONBLOCK  阅读(1735)  评论(0)    收藏  举报

  最近在学Linux的系统调用,总结了一些东西,自己都觉得有点乱了。虽然大部分都是摘录书上的内容或则来自Linux的man pages,不过还是发表在博客上,至少方便将来复习。

 


管道(半双工)

#include <unistd.h>

<一>
int pipe(int fd[2]);

基本描述:
创建一个管道,fd[0]用于读管道,fd[1]用于写管道。

<二>
FILE *popen(const char *command, const char *type);

基本描述:
执行一个shell命令。
type=="r": 返回stdout
type=="w": 返回stdin

<三>
int pclose(FILE *stream);

基本描述:关闭popen返回的文件指针。


FIFO-命名管道(半双工)

#include <sys/types.h>
#include <sys/stat.h>

<一>
int mkfifo(const char *pathname, mode_t mode);
基本描述:
创建一个命名管道(未打开)。
mkfifo中的参数mode隐含了O_CREAT | O_EXCL

管道和FIFO总结

1.管道和FIFO的写入总是往末尾添加数据,读取总是从开头返回数据。

2.不能调用lseek。

3.两个都是半双工。

4.FIFO可以在调用open时指定O_NONBLOCK。管道可以使用fcntl函数进行设置。

5.当要求写入的数据<=PIPE_BUF时,write是原子操作。

6.当要求写入的数据<=PIPE_BUF,
  1)若有足够空间,则一次性写入并能保证操作的原子性。
  2)当空间不足时,如果设置了O_NONBLOCK标志,则直接返回,设置EAGAIN。

7.当要求写入的数据>PIPE_BUF
  1)若有足够空间,则写入----非原子性操作,可能被中断也不一定。
  2)空间不足,有多少写多少。
  3)空间已满,如果设置了O_NONBLOCK,返回,设置EAGAIN。

8.如果向一个没有打开为读的管道或FIFO写入,那么内核将产生一个SIGPIPE信号。该信号默认终止进程。一般情况下,我们可以选择忽略此信号,并且检测write之后的errno==EPIPE。


对比迭代服务器和并发服务器

1.迭代服务器:按顺序处理客户的请求。只有当一个客户的请求处理完成才能轮到下一个请求。这样的服务器延长了客户等待的预期时间。并且容易遭受拒绝服务(DoS)型攻击。

2.并发服务器:典型的并发服务器是“一客户一进程”。即当一个客户请求到达时,服务器就调用fork产生一个子进程来完成客户的请求。除了“一客户一进程”之外,还有
    创建一个子进程池,让池中某一个空闲的子进程为一个新的客户服务。
    为每个客户创建一个线程。
    创建一个线程池,让池中某个空闲的线程为一个新的客户服务。