进程通信的方式对比
管道
管道传输数据时单向的。也是以文件的方式存在。
匿名管道: 函数int pipe(int fd[2]) 返回0成功 unistd.h
管道:是内核缓存的一段数据。 mkfifo sys/types.h sys/stat.h
缺点:效率低,不适合进程间频繁额交换数据。
优点:逻辑简单,能更容易知道数据更新
PIP_BUF通常在1024到5120之间
FIFO管道:FIFOwrite具有原子性
生命周期:进程结束,管道结束。
消息队列
优点:解决管道的缺点
缺点:通信不及时,二是附件也有大小限制。不适合较大数据的传输。
消息队列:保存在内核中的消息链表。每个消息题有固定大小的存储块。读了消息题就会删除消息体。
放在内核的堆里,需要手动释放。
生命周期:与操作系统一样。凌驾于进程之上。
大小:一个队列1024个消息,每个消息8192字节。
在开销上,需要复制4次:
1,由用户空间缓冲区中将数据拷贝到内核空间缓冲区中
2,内核空间缓冲区将数据拷贝到内存中
3,内存将数据拷贝到到内核缓冲区
4,内核空间缓冲区到用户空间缓冲区.
共享内存(mmap, shmget)
数据复制两次
1,用户空间到内存
2,内存到用户空间。
优点:大数据传输,通信及时。
缺点:代码多一点点复杂,但还需信号量一起配合,保护临界资源。
信号量
优点:保护临界资源。
本质:整型的计数器,主要用于实现进程间的互斥和同步,而不是用于缓存进程间通信的数据。
信号量表示资源的数量:
1.P操作:sem -=1 if(sem<0) 表明资源已被占用,进程阻塞等待;else 资源可使用,进程继续执行 lock_the_mutex() sem_wait()
2.V操作:sem +=1 if(sem<=0) 表明当前有阻塞的进程,于是会将该进程唤醒运行;else 表明当前没有阻塞的进程。 lock_the_mutex() sem_post()
信号量初始化为1,代表互斥信号量,为0,代表同步信号量
信号
对于异常情况下的工作模式,就需要该方式通知进程
唯一的异步通信机制。信号产生后,有几种处理方式
1. 执行默认操作
2.捕捉信号,已定义对应的信号处理函数
3. 忽略信号。SIGKILL与SIGSTOP,这是无法捕捉和忽略的。
socket
优点:跨网络,不同主机之间的进程。 int socket(int domain, int type, int protocal)
domain 参数用来指定协议族,比如 AF_INET 用于 IPV4、AF_INET6 用于 IPV6、AF_LOCAL/AF_UNIX 用于本机;
type 参数用来指定通信特性,比如 SOCK_STREAM 表示的是字节流,对应 TCP、SOCK_DGRAM 表示的是数据报,对应 UDP、SOCK_RAW 表示的是原始套接字;
protocal 参数原本是用来指定通信协议的,但现在基本废弃。因为协议已经通过前面两个参数指定完成,protocol 目前一般写成 0 即可;