Unix域协议与多路复用
Unix域协议
Unix域协议是一种IPC(进程间通信) 方式,使用Socket编程接口实现本地进程间通信。其特点如下:
协议簇与套接字类型
- 协议簇:
AF_UNIX或AF_LOCAL(区别于AF_INETIPv4)。 - 套接字类型:
SOCK_DGRAM:类似UDP的数据报套接字(无连接)。SOCK_STREAM:类似TCP的流式套接字(面向连接)。
网络地址结构
使用文件系统路径作为地址(需以 \0 结尾):
c
#include <sys/un.h>
struct sockaddr_un {
sa_family_t sun_family; // 协议簇(AF_UNIX)
char sun_path[104]; // 套接字文件路径(如 "/tmp/xxx.socket")
};使用场景
- 优势:数据不经过网卡,直接在内核中传输,效率高于IPv4协议。
- 典型应用:本地进程间高速通信(如数据库守护进程与客户端交互)。
多路复用
多路复用用于同时监听多个文件描述符的就绪状态(可读/可写/异常),避免阻塞等待。
阻塞IO的局限性
- 读操作:无数据时,
read会阻塞直到数据到达。 - 写操作:无缓冲区空间时,
write会阻塞直到可写入。
1. select
c
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);- 参数:
nfds:最大文件描述符值 + 1。readfds/writefds/exceptfds:监听读/写/异常的描述符集合(传入需监听的描述符,返回就绪的描述符)。timeout:超时时间(NULL表示无限等待)。
- 返回值:
>0:就绪的描述符数量。=0:超时。<0:出错。
描述符集合操作函数
c
void FD_ZERO(fd_set *set); // 清空集合
void FD_SET(int fd, fd_set *set); // 添加描述符到集合
void FD_CLR(int fd, fd_set *set); // 从集合移除描述符
int FD_ISSET(int fd, fd_set *set); // 检查描述符是否在集合中2. poll
c
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);- 参数:
fds:struct pollfd结构体数组(每个元素描述一个监听请求)。nfds:数组元素个数。timeout:超时时间(毫秒)。
struct pollfd结构:cstruct pollfd { int fd; // 文件描述符 short events; // 监听的事件(如 POLLIN 可读、POLLOUT 可写) short revents; // 返回就绪的事件 };- 返回值:同
select。
3. epoll(高效多路复用)
创建实例
c
#include <sys/epoll.h>
int epoll_create(int size); // size > 0(历史遗留,可忽略)
// 成功返回 epoll 文件描述符,失败返回 -1管理监听事件
c
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);- 参数:
epfd:epoll_create返回的描述符。op:操作类型(EPOLL_CTL_ADD添加、EPOLL_CTL_DEL删除、EPOLL_CTL_MOD修改)。fd:需监听的文件描述符。event:监听事件结构体指针:cstruct epoll_event { uint32_t events; // 监听事件(如 EPOLLIN、EPOLLOUT) epoll_data_t data; // 用户数据 }; typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t;
等待事件就绪
c
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);- 参数:
events:输出参数,存储就绪事件的结构体数组。maxevents:数组最大容量。timeout:超时时间(毫秒)。
- 返回值:同
select。
触发模式
- 水平触发(LT):
- 只要描述符就绪,持续上报事件(默认模式)。
- 边缘触发(ET):
- 仅在状态变化时上报一次事件(需设置
EPOLLET标志)。
- 仅在状态变化时上报一次事件(需设置
效率对比
| 机制 | 效率 | 特点 |
|---|---|---|
select | 低(O(n)轮询) | 支持文件描述符数量有限(通常1024) |
poll | 中(O(n)轮询) | 无描述符数量限制 |
epoll | 高(O(1)事件通知) | 支持边缘触发,适合高并发场景 |
总结
- Unix域协议:通过文件路径标识地址,实现本地进程间高效通信。
- 多路复用:
select/poll:适用于少量描述符监听。epoll:适用于高并发场景,支持边缘触发模式。
