一、管道pipe
实质是一个内核缓冲区,linux中使用环形队列实现,进程以先进先出的方式从缓冲区存取数据。
特点:
-
是半双工的(数据只能在一个方向上流动),具有固定的读端和写端
-
只能用于有亲缘关系的进程之间进行通信
-
当缓冲区空或者满时,读进程或写进程会阻塞
-
管道中的数据只能被读取一次,读取后便从管道中消失
二、命名管道FIFO
与无名管道pipe的区别:
-
有一个名字,并且是一个真实存在(指在文件系统中可以通过inode进行访问)的可以打开、删除的文件
-
任意进程都可以使用,不只是亲缘关系
三、消息队列Message Queue
保存在内核中,用链表进行实现
与管道的区别:
对每个消息制定特定的消息类型,读写时不是先进先出的方式进行,而是可以自定义接受特定类型的消息
四、共享存储SharedMemory
将一块内存映射到不同进程的虚拟空间(页表)中,实现内存的共享
一定会存在同步的问题,但操作系统并未主动提供控制,需要使用者自己进行同步控制
使用引用计数原理,每个共享内存中有一个计数器记录当前共享其数据的进程数目,避免删除该内存导致共享该内存的进程出错
共享内存的速度比使用普通文件(如管道和消息队列)更快
使用共享内存时,数据直接在内存上操作,而使用文件则需要和内核以及磁盘进行交互。当共享结束后才将共享内存中数据写回磁盘
两种实现方式
1.内存映射
将整个或部分文件映射到内存中,进程直接从内存中访问该文件。其主要优点是绕开了内核,提高了利用效率
2.共享内存
不是文件,而是内存中的一块区域(一般位于进程空间的堆与栈之间)进行共享,在使用后也无需写回等操作
五、信号量Semaphore
是一个计数器,主要用于实现进程间的同步,可以和共享内存结合进行消息的通信
基于操作系统的P、V原语
阻塞机制
当一个进程获取信号量失败时,会让出CPU并加入等待队列即阻塞,而不是自旋
因此要求只有能够阻塞的进程才可以使用信号量,例如中断处理程序中,由于中断需要立刻完成因此不能阻塞,因此不能使用信号量
信号量和锁的区别
信号量不一定是锁定某一个资源,也可以用于流程的控制,而锁就单纯是一个锁住资源的概念
在管程(Monitor)中就使用锁进行了资源锁定、信号量进行流程控制
六、套接字Socket
是计算机网络的概念
socket = ip + port,ip可以唯一标识一个主机,而port可以唯一标识指定主机上的一个进程,因此socket可以唯一标识一个进程
七、信号Signal
信号是内核发送给进程的信息,windows下称为消息
为什么要发送?
一种原因是操作系统中出现了一些状况需要进程知道 (比如除0、子进程终止等)
另外一种情况是有进程显式调用了kill函数要求内核向指定进程发送信号
怎么“发送”?
实际上信号并不是一条一条的信息,而是在进程PCB中的结构
每个进程的PCB中有三个”数组”(标志位)以实现信号:
1.blocking
标识该进程阻塞即不接受的信号
2.pending
标志位,每一位代表一个信号
3.delivery
指针数组,指向每一个信号对应的处理程序
怎么处理信号?
当进程从内核态切换至用户态时,会检查PCB中的标志位,如果标志位为1则转入delivery中的信号处理程序进行处理
信号是不排队的
从PCB中pending的结构我们看出,每个信号只是一个标志位,并不存在队列等结构。也就是说,无论内核向进程发送了多少信号A,其结果都表示为A的标志位为1,进程是无法感知信号A的数量的,只能感知到0和1的boolean值即是否有该信号
信号处理程序
由delivery的结构我们不难看出,信号处理程序是可以用户自定义的,且不用进程之间可以不同的。
当然,并不是所有的信号都可以自定义处理程序。比如sigstop(暂停当前进程)和sigkill(终止当前进程)
标签:通信,信号量,内核,信号,进程,共享内存,内存 来源: https://www.cnblogs.com/harryW/p/15710518.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。