zoukankan      html  css  js  c++  java
  • IPC note

    IPC分类

    通信、同步、信号

    通信:
    管道、FIFO、流socket
    伪终端
    消息队列、数据报socket
    共享内存、内存映射(匿名映射、映射文件)

    管道

    写入数据量不超过PIPE_BUF字节的写入操作是原子的。

    FIFO

    FIFO在文件系统中拥有一个名称,并且其打开方式与打开一个普通文件相同。

    #include <sys/stat.h>
    int mkfifo(const char *pathname, mode_t mode);
    

    默认情况下,打开一个FIFO以便读取数据(open() O_RDONLY标记)将会阻塞直到另一个进程打开FIFO以写入数据(open() O_WRONLY)为止。
    相应地,打开一个FIFO以写入数据会阻塞直到另一个进程打开FIFO以读取数据。

    避免阻塞可以打开的时候添加O_NONBLOCK标记。

    两个作用

    1. 允许单个进程先后打开同一个FIFO的两端。
    2. 防止两个FIFO的进程之间发生死锁。如X进程打开A再打开B,Y进程打开B再打开A。

    select

    http://janfan.cn/chinese/2015/01/05/select-poll-impl-inside-the-kernel.html

    一遍轮询, 对每个文件描述符, 做一次struct file_operations结构体里的poll操作。

    int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
    {
    	// …
    	for (;;) {
    		// …
    		for (i = 0; i < n; ++rinp, ++routp, ++rexp) {
    			// …
    			struct fd f;
    			f = fdget(i);
    			if (f.file) {
    				const struct file_operations *f_op;
    				f_op = f.file->f_op;
    				mask = DEFAULT_POLLMASK;
    				if (f_op->poll) {
    					wait_key_set(wait, in, out,
    						     bit, busy_flag);
    					// 对每个fd进行I/O事件检测
    					mask = (*f_op->poll)(f.file, wait);
    				}
    				fdput(f);
    				// …
    			}
    		}
    		// 退出循环体
    		if (retval || timed_out || signal_pending(current))
    			break;
    		// 进入休眠
    		if (!poll_schedule_timeout(&table, TASK_INTERRUPTIBLE,
    				to, slack))
    			timed_out = 1;
    	}
    }
    

    (*f_op->poll)会返回当前设备fd的状态(比如是否可读可写),根据这个状态,do_select()接着做出不同的动作。
    select()把全部fd检测一轮之后如果没有可用I/O事件,会让当前进程去休眠一段时间,等待fd设备或定时器来唤醒自己,然后再继续循环体看看哪些fd可用,以此提高效率。

    缺点:
    1.所能监视的文件描述符的数量有限制,sizeof(fd_set)=128,说明能监视的描述符的最大值为128*8=1024个
    2.同时每次调用select都需要在内核遍历传递进来的所有fd,当fd很多时性能会下降
    3.由于当有事件发生时,select返回后会修改三个事件集,所以,每次都需要把fd集合从用户区拷贝到内核区,当需要监视的fd数量增多时,性能会下降

    poll

    优点:
    1.相比select来讲,它没有fd数量的限制,理论上打开fd的数目跟系统内在有关
    2.也不用每次都把fd集合从用户区拷贝数据到内核,它使用一个 struct pollfd结构体来维护每个fd
    缺点:
    它本质上是和selece一样的,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多

    epoll

    优点:
    具备了select所不具备的所有优点
    1.没有fd数量的限制,它所支持的fd上限是最大可以打开文件的数目,具体数目可cat/proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大
    2.epoll_ctl每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝,epoll保证了每个fd在整个过程中只会拷贝一次
    3.epoll的解决方案不像select或poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表)。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd

    适用场景:
    当活动连接比较多的时候,epoll_wait的效率未必比select和poll高,因为此时回调函数被触发的过于频繁,因此epoll_wait适用于连接数量多,但活动连接较少的情况

    epoll对文件描述符的操作有两种模式:LT和ET

    LT(水平触发):这种模式是默认的工作模式,此时,epoll相当于效率较高的poll,当往epoll内核事件表中注册一个文件描述符上的EPOLLET事件时,epoll将以ET模式来操作该文件描述符
    ET(边沿触发):ET模式是epoll的高效工作模式,它在很大程度上降低了同一个epoll事件被重复触发的次数

    https://zhuanlan.zhihu.com/p/22834126

  • 相关阅读:
    用C#实现在线升级
    wordwrap,wordbreak,whitespace,textoverflow的区别和用法[转]
    Sql Server 存储过程分页大全(2005,2000)
    C#中生成中文繁体web页面
    如何在c#里执行sql server DTS包
    asp.net采集函数(采集、分析、替换、入库)
    css定义一个导航栏
    mssql与access的sql语法差异
    [转]sql server数据库定时自动备份
    HttpHandler与图片盗链
  • 原文地址:https://www.cnblogs.com/dirge/p/12785535.html
Copyright © 2011-2022 走看看