1

本文除了介绍linux的进程通信方法,后面细化了select等IO就绪等条件。
clipboard.png

clipboard.png

1.管道 字节流 顺序(不能lseek),单向,相关进程(继承fd) pipe() fds[2]
空管道读阻塞,关闭返回0,
写入不超过PIPE_BUF是原子的,超过可能交叉写入,满write阻塞
FIFO 有名称的管道(在文件系统中),可用于非相关进程之间

2.systemV ipc对象 内核持久
共享内存中指针要是偏移量

3.posix mq_open(消息队列) shm_open+mmap(共享内存) 内核持久
mq:描述符和文件类似,进程级别句柄
异步通过直mq_notify 只有一个进程可注册,只有边缘触发,收到后要再次注册,一次性
posix的共享内存。linux的tmpfs上,内核持久性。无关进程共享,mmap只能用共享文件映射,必须用磁盘。posix可以不用磁盘。sysV需要一整套新的系统调用和命令。shm_open+mmap

4.内存映射mmap
私有文件映射:共享库等初始化
私有匿名映射:分配新内存,大块内存,fork。
共享文件映射:减少拷贝,节省一个缓冲区(只有一个内核缓冲区).msync控制文件同步
共享匿名映射:共享RAM页。相关进程才能通信
预留 交换空间 OOM

mlock 将虚拟内存区域锁进RAM

5.socket
流/数据报(connect也能提升性能) unix内核/inet/inet6
5.1
Unix socketaddr_un{sa_family_t,sun_path}
socketpair() 相当于双向管道,对其他进程不可见。除非有sun_path,否则无名的或者为NULL的这种抽象namespace的都是相关进程才可见。
file无name比如netsocket,pipe等,不在filesystem namespace中,只能相关进程访问,除非fd passing。这种无inode,否则有inode
5.2 inet domain
地址若是数字有大小端区分。用系统调用htons等
readn,writen
shutdown(write有缓冲区,sendfile无,加tcp_cork数据和并)
recv,send
sendfile
sendmsg/recvmsg 可以实现recv,send等分散聚合功能。常用于同一个主机传递fd面舒服

IO
select(nfds,readxx) nfds比要检查的fd大1,read等感兴趣位图和结果位图,要遍历
什么是就绪?IO不阻塞就是就绪,普通文件一直不阻塞,不能用
select和poll都是水平触发
信号驱动IO IO/文件nofity 边缘触发
epoll 可边缘/水平。
边缘:注意不再通知,还要注意防止饥饿。维护一个就绪文件描述符列表,读到EAGAIN移除,循环读取处理

socket可读可写条件:
clipboard.png
UDP 用connect
没有三路握手过程。相反内核只是检查是否存在立即可知的错误(例如一个显然不可达的目的地),记录对端的IP地址和端口号(取自传递给connect的套接口地址结构),然后立即返回到调用进程。
对于已连接UDP套接口,与缺省的未连接套接口相比:1 我们再也不能给输出操作指定宿IP和端口号,也就是说我们不使用sendto/recvfrom,而改用write或send/read,recv,2.由已连接的UDP套接口引发的异步错误,返回给他们所在的进程。相反我们说过,未连接UDP套接口不接收任何异步错误给一个UDP套接口。
好处:1)选定了对端,内核只会将帮定对象的对端发来的数据报传给套接口,因此在一定环境下可以提升安全性;2)会返回异步错误,如果对端没启动,默认情况下发送的包对应的ICMP回射包不会给调用进程,如果用了connect,嘿嘿3)发送两个包间不要先断开再连接,提升了效率
多次调用connect拥有一个已连接UDP套接口的进程可以为下列2个目的之一:a.指定新的IP地址和端口号; b.断开套接口 .
UDP客户端在建立了插口后会直接用sendto函数发送数据,还隐含了一个操作,那就是在发送数据之前,UDP会首先为该插口选择一个独立的UDP端口(在1024-5000之间),将该插口置为已绑定状态。如果一个UDP客户端在建立了插口后。首先用bind函数指明了本地地址/端口,也是可以的


梦想家
107 声望76 粉丝

引用和评论

0 条评论