射频指标

射频指标,第1张

描述射频信号指标

接收灵敏度,这应该是最基本的概念之一,表征的是接收机能够在不超过一定误码率的情况下识别的最低信号强度。

讲灵敏度的时候我们常常联系到SNR(信噪比,我们一般是讲接收机的解调信噪比),我们把解调信噪比定义为不超过一定误码率的情况下解调器能够解调的信噪比门限(面试的时候经常会有人给你出题,给一串NF、Gain,再告诉你解调门限要你推灵敏度)。那么S和N分别何来? 

S即信号Signal,或者称为有用信号;N即噪声Noise,泛指一切不带有有用信息的信号。有用信号一般是通信系统发射机发射出来,噪声的来源则是非常广泛的,最典型的就是那个著名的-174dBm/Hz——自然噪声底,要记住它是一个与通信系统类型无关的量,从某种意义上讲是从热力学推算出来的(所以它跟温度有关);另外要注意的是它实际上是个噪声功率密度(所以有dBm/Hz这个量纲),我们接收多大带宽的信号,就会接受多大带宽的噪声——所以最终的噪声功率是用噪声功率密度对带宽积分得来。

发射功率的重要性,在于发射机的信号需要经过空间的衰落之后才能到达接收机,那么越高的发射功率意味着越远的通信距离。 

那么我们的发射信号要不要讲究SNR?譬如说,我们的发射信号SNR很差,那么到达接收机的信号SNR是不是也很差? 

这个牵涉到刚才讲过的概念,自然噪声底。我们假设空间的衰落对信号和噪声都是效果相同的(实际上不是,信号能够通编码抵御衰落而噪声不行)而且是如同衰减器一般作用的,那么我们假设空间衰落-200dB,发射信号带宽1Hz,功率50dBm,信噪比50dB,接收机收到信号的SNR是多少? 

接收机收到信号的功率是50-200=-150Bm(带宽1Hz),而发射机的噪声50-50=0dBm通过空间衰落,到达接收机的功率是0-200=-200dBm(带宽1Hz)?这时候这部分噪声早已被“淹没”在-174dBm/Hz的自然噪声底之下了,此时我们计算接收机入口的噪声,只需要考虑-174dBm/Hz的“基本成分”即可。 

这在通信系统的绝大部分情况下是适用的。

我们把这些项目放在一起,是因为它们表征的实际上是“发射机噪声”的一部分,只是这些噪声不是在发射信道之内,而是发射机泄漏到临近信道中去的部分,可以统称为“邻道泄漏”。 

其中ACLR和ACPR(其实是一个东西,不过一个是在终端测试中的叫法,一个是在基站测试中的叫法罢了),都是以“Adjacent Channel”命名,顾名思义,都是描述本机对其他设备的干扰。而且它们有个共同点,对干扰信号的功率计算也是以一个信道带宽为计。这种计量方法表明,这一指标的设计目的,是考量发射机泄漏的信号,对相同或相似制式的设备接收机的干扰——干扰信号以同频同带宽的模式落到接收机带内,形成对接收机接收信号的同频干扰。 

在LTE中,ACLR的测试有两种设置,EUTRA和UTRA,前者是描述LTE系统对LTE系统的干扰,后者是考虑LTE系统对UMTS系统的干扰。所以我们可以看到EUTRA ACLR的测量带宽是LTE RB的占用带宽,UTRA ACLR的测量带宽是UMTS信号的占用带宽(FDD系统3.84MHz,TDD系统1.28MHz)。换句话说,ACLR/ACPR描述的是一种“对等的”干扰:发射信号的泄漏对同样或者类似的通信系统发生的干扰。 

这一定义是有非常重要的实际意义的。实际网络中同小区邻小区还有附近小区经常会有信号泄漏过来,所以网规网优的过程实际上就是容量最大化和干扰最小化的过程,而系统本身的邻道泄漏对于邻近小区就是典型的干扰信号;从系统的另一个方向来看,拥挤人群中用户的手机也可能成为互相的干扰源。 

同样的,在通信系统的演化中,从来是以“平滑过渡”为目标,即在现有网络上升级改造进入下一代网络。那么两代甚至三代系统共存就需要考虑不同系统之间的干扰,LTE引入UTRA即是考虑了LTE在与UMTS共存的情形下对前代系统的射频干扰。

讲SEM的时候,首先要注意它是一个“带内指标”,与spurious emission区分开来,后者在广义上是包含了SEM的,但是着重看的其实是发射机工作频段之外的频谱泄漏,其引入也更多的是从EMC(电磁兼容)的角度。 

SEM是提供一个“频谱模版”,然后在测量发射机带内频谱泄漏的时候,看有没有超出模版限值的点。可以说它与ACLR有关系,但是又不相同:ACLR是考虑泄漏到邻近信道中的平均功率,所以它以信道带宽为测量带宽,它体现的是发射机在邻近信道内的“噪声底”;SEM反映的是以较小的测量带宽(往往100kHz到1MHz)捕捉在邻近频段内的超标点,体现的是“以噪声底为基础的杂散发射”。 

如果用频谱仪扫描SEM,可以看到邻信道上的杂散点会普遍的高出ACLR均值,所以如果ACLR指标本身没有余量,SEM就很容易超标。反之SEM超标并不一定意味着ACLR不良,有一种常见的现象就是有LO的杂散或者某个时钟与LO调制分量(往往带宽很窄,类似点频)串入发射机链路,这时候即便ACLR很好,SEM也可能超标。 

首先,EVM是一个矢量值,也就是说它有幅度和角度,它衡量的是“实际信号与理想信号的误差”,这个量度可以有效的表达发射信号的“质量”——实际信号的点距离理想信号越远,误差就越大,EVM的模值就越大。 

很难定义EVM与ACPR/ACLR的定量关系,从放大器的非线性来看,EVM与ACPR/ACLR应该是正相关的:放大器的AM-AM、AM-PM失真会扩大EVM,同时也是ACPR/ACLR的主要来源。 

但是EVM与ACPR/ACLR并不总是正相关,我们这里可以找到一个很典型的例子:数字中频中常用的Clipping,即削峰。Clipping是削减发射信号的峰均比(PAR),峰值功率降低有助于降低通过PA之后的ACPR/ACLR;但是Clipping同时会损害EVM,因为无论是限幅(加窗)还是用滤波器方法,都会对信号波形产生损伤,因而增大EVM。 

PAR(信号峰均比)通常用CCDF这样一个统计函数来表示,其曲线表示的是信号的功率(幅度)值和其对应的出现概率。譬如某个信号的平均功率是10dBm,它出现超过15dBm功率的统计概率是0.01%,我们可以认为它的PAR是5dB。 

所以对于正弦波,假设他的峰值是4,那么他的峰值功率就是4^2=16;而他的平均功率计算

t = [0:0.01:4*pi]

a = 4 * sin(t)

% b = fft(a, 1024)

% plot(abs(b))

result = sum(a.^2)/length(t)

计算得到的结果是8,也就是4^2/2=8;所以他的PAR是3dB。

PAR是现代通信系统中发射机频谱再生(诸如ACLP/ACPR/Modulation Spectrum)的重要影响因素。峰值功率会将放大器推入非线性区从而产生失真,往往峰值功率越高、非线性越强。 

在GSM时代,因为GMSK调制的衡包络特性,所以PAR=0,我们在设计GSM功放的时候经常把它推到P1dB,以得到最大限度的效率。引入EDGE之后,8PSK调制不再是衡包络,因此我们往往将功放的平均输出功率推到P1dB以下3dB左右,因为8PSK信号的PAR是3.21dB。 

UMTS时代,无论WCDMA还是CDMA,峰均比都比EDGE大得多。原因是码分多址系统中信号的相关性:当多个码道的信号在时域上叠加时,可能出现相位相同的情况,此时功率就会呈现峰值。 

LTE的峰均比则是源自RB的突发性。OFDM调制是基于将多用户/多业务数据在时域上和频域上都分块的原理,这样就可能在某一“时间块”上出现大功率。LTE上行发射用SC-FDMA,先用DFT将时域信号扩展到频域上,等于“平滑”掉了时域上的突发性,从而降低了PAR。 

这里的“干扰指标”,指的是出了接收机静态灵敏度之外,各种施加干扰下的灵敏度测试。实际上研究这些测试项的由来是很有意思的。 

我们常见的干扰指标,包括Blocking,Desense,Channel Selectivity等。 

Blocking实际上是一种非常古老的RF指标,早在雷达发明之初就有。其原理是以大信号灌入接收机(通常最遭殃的是第一级LNA),使得放大器进入非线性区甚至饱和。此时一方面放大器的增益骤然变小,另一方面产生极强非线性,因而对有用信号的放大功能就无法正常工作了。 

另一种可能的Blocking其实是通过接收机的AGC来完成的:大信号进入接收机链路,接收机AGC因此产生动作降低增益以确保动态范围;但是同时进入接收机的有用信号电平很低,此时增益不足,进入到解调器的有用信号幅度不够。 

Blocking指标分为带内和带外,主要是因为射频前端一般会有频带滤波器,对于带外blocking会有抑制作用。但是无论带内还是带外,Blocking信号一般都是点频,不带调制。事实上完全不带调制的点频信号在现实世界里并不多见,工程上只是把它简化成点频,用以(近似)替代各种窄带干扰信号。 

对于解决Blocking,主要是RF出力,说白了就是把接收机IIP3提高,动态范围扩大。对于带外Blocking,滤波器的抑制度也是很重要的。 

When the defined useful signal coexist with blocking signal, throughput loss less than 1%

useful signal  = PREFSENS + 14dB, 20MHz, -79.5dBm

这里我们统称为“邻信道选择性”。在蜂窝系统中,我们组网除了要考虑同频小区,还要考虑邻频小区,其原因可以在我们之前讨论过的发射机指标ACLR/ACPR/Modulation Spectrum中可以找到:因为发射机的频谱再生会有很强的信号落到相邻频率中(一般来说频偏越远电平越低,所以邻信道一般是受影响最大的),而且这种频谱再生事实上是与发射信号有相关性的,即同制式的接收机很可能把这部分再生频谱误认为是有用信号而进行解调,所谓鹊巢鸠占。 

举个例子:如果两个相邻小区A和B恰好是邻频小区(一般会避免这样的组网方式,这里只是讨论一个极限场景),当一台注册到A小区的终端游走到两个小区交界处,但是两个小区的信号强度还没有到切换门限,因此终端依然保持A小区连接;B小区基站发射机的ACPR较高,因此终端的接收频带内有较高的B小区ACPR分量,与A小区的有用信号在频率上重叠;因为此时终端距离A小区基站较远,因此接收到的A小区有用信号强度也很低,此时B小区ACPR分量进入到终端接收机时就可以对原有用信号造成同频干扰。 

如果我们注意看邻道选择性的频偏定义,会发现有Adjacent和Alternative的区别,对应ACLR/ACPR的第一邻道、第二邻道,可见通信协议中“发射机频谱泄漏(再生)”与“接收机邻道选择性”实际上是成对定义的。 

When the defined useful signal coexist with interference signal, throughput loss less than 1%

Blocking是“大信号干扰小信号”,RF尚有周旋余地;而以上的AM Suppression, Adjacent (Co/Alternative) Channel Suppression (Selectivity)这些指标,是“小信号干扰大信号”,纯RF的工作意义不大,还是靠物理层算法为主。 

这种描述的是绝对的同频干扰,一般是指两个同频小区之间的干扰模式。 

按照之前我们描述的组网原则,两个同频小区的距离应该尽量远,但是即便再远,也会有信号彼此泄漏,只是强度高低的区别。

对于终端而言,两个小区的信号都可以认为是“正确的有用信号”(当然协议层上有一组接入规范来防范这种误接入),衡量终端的接收机能否避免“西风压倒东风”,就看它的同频选择性。 

动态范围,温度补偿和功率控制很多情况下是“看不到”的指标,只有在进行某些极限测试的时候才会表现出它们的影响,但是本身它们却体现着RF设计中最精巧的部分。 

发射机动态范围表征的是发射机“不损害其他发射指标前提下”的最大发射功率和最小发射功率。 

“不损害其他发射指标”显得很宽泛,如果看主要影响,可以理解为:最大发射功率下不损害发射机线性度,最小发射功率下保持输出信号信噪比。 

最大发射功率下,发射机输出往往逼近各级有源器件(尤其末级放大器)的非线性区,由此经常发生的非线性表现有频谱泄漏和再生(ACLR/ACPR/SEM),调制误差(PhaseError/EVM)。此时最遭殃的基本上都是发射机线性度,这一部分应该比较好理解。 

最小发射功率下,发射机输出的有用信号则是逼近发射机噪声底,甚至有被“淹没”在发射机噪声中的危险。此时需要保障的是输出信号的信噪比(SNR),换句话说就是在最小发射功率下的发射机噪声底越低越好。 

在实验室曾经发生过一件事情:有工程师在测试ACLR的时候,发现功率降低ACLR反而更差(正常理解是ACLR应该随着输出功率降低而改善),当时第一反应是仪表出问题了,但是换一台仪表测试结果依然如此。我们给出的指导意见是测试低输出功率下的EVM,发现EVM性能很差;我们判断可能是RF链路入口处的噪声底就很高,对应的SNR显然很差,ACLR的主要成分已经不是放大器的频谱再生、而是通过放大器链路被放大的基带噪声。 

接收机动态范围其实与之前我们讲过的两个指标有关,第一个是参考灵敏度,第二个是接收机IIP3(在讲干扰指标的时候多次提到)。 

参考灵敏度实际上表征的就是接收机能够识别的最小信号强度,这里不再赘述。我们主要谈一下接收机的最大接收电平。

最大接收电平是指接收机在不发生失真情况下能够接收的最大信号。这种失真可能发生在接收机的任何一级,从前级LNA到接收机ADC。对于前级LNA,我们唯一可做的就是尽量提高IIP3,使其可以承受更高的输入功率;对于后面逐级器件,接收机则采用了AGC(自动增益控制)来确保有用信号落在器件的输入动态范围之内。简单的说就是有一个负反馈环路:检测接收信号强度(过低/过高)-调整放大器增益(调高/调低)-放大器输出信号确保落在下一级器件的输入动态范围之内。 

这里我们讲一个例外:多数手机接收机的前级LNA本身就带有AGC功能,如果你仔细研究它们的datasheet,会发现前级LNA会提供几个可变增益段,每个增益段有其对应的噪声系数,一般来讲增益越高、噪声系数越低。这是一种简化的设计,其设计思想在于:接收机RF链路的目标是将输入到接收机ADC的有用信号保持在动态范围之内,且保持SNR高于解调门限(并不苛求SNR越高越好,而是“够用就行”,这是一种很聪明的做法)。因此当输入信号很大时,前级LNA降低增益、损失NF、同时提高IIP3;当输入信号小时,前级LNA提高增益、减小NF、同时降低IIP3。 

一般来讲,我们只在发射机作温度补偿。 

当然,接收机性能也是受到温度影响的:高温下接收机链路增益降低,NF增高;低温下接收机链路增益提高,NF降低。但是由于接收机的小信号特性,无论增益还是NF的影响都在系统冗余范围之内。 

对于发射机温度补偿,也可以细分为两部分:一部分是对发射信号功率准确度的补偿,另一部分是对发射机增益随温度变化进行补偿。 

现代通信系统发射机一般都进行闭环功控(除了略为“古老”的GSM系统和Bluetooth系统),因此经过生产程序校准的发射机,其功率准确度事实上取决于功控环路的准确度。一般来讲功控环路是小信号环路,且温度稳定性很高,所以对其进行温度补偿的需求并不高,除非功控环路上有温度敏感器件(譬如放大器)。 

对发射机增益进行温度补偿则更加常见。这种温度补偿常见的有两种目的:一种是“看得见的”,通常对没有闭环功控的系统(如前述GSM和Bluetooth),这类系统通常对输出功率精确度要求不高,所以系统可以应用温度补偿曲线(函数)来使RF链路增益保持在一个区间之内,这样当基带IQ功率固定而温度发生变化时,系统输出的RF功率也能保持在一定范围之内;另一种是“看不见的”,通常是在有闭环功控的系统中,虽然天线口的RF输出功率是由闭环功控精确控制的,但是我们需要保持DAC输出信号在一定范围内(最常见的例子是基站发射系统数字预失真(DPD)的需要),那么我们就需要将整个RF链路的增益比较精确的控制在某个值左右——温补的目的就在于此。 

发射机温补的手段一般有可变衰减器或者可变放大器:早期精度稍低以及低成本精度要求较低的情况下,温补衰减器比较常见;对精度要求更高的情形下,解决方案一般是:温度传感器+数控衰减器/放大器+生产校准。 

讲完动态范围和温度补偿,我们来讲一个相关的、而且非常重要的概念:功率控制。 

发射机功控是大多数通信系统中必需的功能,在3GPP中常见的诸如ILPC、OLPC、CLPC,在RF设计中都是必需被测试、经常出问题、原因很复杂的。我们首先来讲发射机功控的意义。 

所有的发射机功控目的都包含两点:功耗控制和干扰抑制。 

我们首先说功耗控制:在移动通信中,鉴于两端距离变化以及干扰电平高低不同,对发射机而言,只需要保持“足够让对方接收机准确解调”的信号强度即可;过低则通信质量受损,过高则空耗功率毫无意义。对于手机这样以电池供电的终端更是如此,每一毫安电流都需锱铢必量。 

干扰抑制则是更加高级的需求。在CDMA类系统中,由于不同用户共享同一载频(而以正交用户码得以区分),因此在到达接收机的信号中,任何一个用户的信号对于其他用户而言,都是覆盖在同一频率上的干扰,若各个用户信号功率有高有高低,那么高功率用户就会淹没掉低功率用户的信号;因此CDMA系统采取功率控制的方式,对于到达接收机的不同用户的功率(我们称之为空中接口功率,简称空口功率),发出功控指令给每个终端,最终使得每个用户的空口功率一样。这种功控有两个特点:第一是功控精度非常高(干扰容限很低),第二是功控周期非常短(信道变化可能很快)。 

在LTE系统中,上行功控也有干扰抑制的作用。因为LTE上行是SC-FDMA,多用户也是共享载频,彼此间也互为干扰,所以空口功率一致同样也是必需的。 

GSM系统也是有功控的,GSM中我们用“功率等级”来表征功控步长,每个等级1dB,可见GSM功率控制是相对粗糙的。 

这里提一个相关的概念:干扰受限系统。CDMA系统是一个典型的干扰受限系统。从理论上讲,如果每个用户码都完全正交、可以通过交织、解交织完全区分开来,那么实际上CDMA系统的容量可以是无限的,因为它完全可以在有限的频率资源上用一层层扩展的用户码区分无穷多的用户。但是实际上由于用户码不可能完全正交,因此在多用户信号解调时不可避免的引入噪声,用户越多噪声越高,直到噪声超过解调门限。 

换而言之,CDMA系统的容量受限于干扰(噪声)。 

GSM系统不是一个干扰受限系统,它是一个时域和频域受限的系统,它的容量受限于频率(200kHz一个载频)和时域资源(每个载频上可共享8个TDMA用户)。所以GSM系统的功控要求不高(步长较粗糙,周期较长)。 

讲完发射机功控,我们进而讨论一下在RF设计中可能影响发射机功控的因素(相信很多同行都遇到过闭环功控测试不过的郁闷场景)。 

对于RF而言,如果功率检测(反馈)环路设计无误,那么我们对发射机闭环功控能做的事情并不多(绝大多数工作都是由物理层协议算法完成的),最主要的就是发射机带内平坦度。 

因为发射机校准事实上只会在有限的几个频点上进行,尤其在生产测试中,做的频点越少越好。但是实际工作场景中,发射机是完全可能在频段内任一载波工作的。在典型的生产校准中,我们会对发射机的高中低频点进行校准,意味着高中低频点的发射功率是准确的,所以闭环功控在进行过校准的频点上也是无误的。然而,如果发射机发射功率在整个频段内不平坦,某些频点的发射功率与校准频点偏差较大,因此以校准频点为参考的闭环功控在这些频点上也会发生较大误差乃至出错。

在操作系统中,一个进程可以理解为是关于计算机资源集合的一次运行活动,其就是一个正在执行的程序的实例。从概念上来说,一个进程拥有它自己的虚拟CPU和虚拟地址空间,任何一个进程对于彼此而言都是相互独立的,这也引入了一个问题 —— 如何让进程之间互相通信?

由于进程之间是互相独立的,没有任何手段直接通信,因此我们需要借助操作系统来辅助它们。举个通俗的例子,假如A与B之间是独立的,不能彼此联系,如果它们想要通信的话可以借助第三方C,比如A将信息交给C,C再将信息转交给B —— 这就是进程间通信的主要思想 —— 共享资源。

这里要解决的一个重要的问题就是如何避免竞争,即避免多个进程同时访问临界区的资源。

共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。

你可能会想到,我直接创建一个文件,然后进程不就都可以访问了?

是的,但这个方法有几个缺陷:

Linux下采用共享内存的方式来使进程完成对共享资源的访问,它将磁盘文件复制到内存,并创建虚拟地址到该内存的映射,就好像该资源本来就在进程空间之中,此后我们就可以像操作本地变量一样去操作它们了,实际的写入磁盘将由系统选择最佳方式完成,例如操作系统可能会批量处理加排序,从而大大提高IO速度。

如同上图一样,进程将共享内存映射到自己的虚拟地址空间中,进程访问共享进程就好像在访问自己的虚拟内存一样,速度是非常快的。

共享内存的模型应该是比较好理解的:在物理内存中创建一个共享资源文件,进程将该共享内存绑定到自己的虚拟内存之中。

这里要解决的一个问题是如何将同一块共享内存绑定到自己的虚拟内存中,要知道在不同进程中使用 malloc 函数是会顺序分配空闲内存,而不会分配同一块内存,那么要如何去解决这个问题呢?

Linux操作系统已经想办法帮我们解决了这个问题,在 #include <sys/ipc.h>和 #include <sys/shm.h>头文件下,有如下几个shm系列函数:

通过上述几个函数,每个独立的进程只要有统一的共享内存标识符便可以建立起虚拟地址到物理地址的映射,每个虚拟地址将被翻译成指向共享区域的物理地址,这样就实现了对共享内存的访问。

还有一种相像的实现是采用mmap函数,mmap通常是直接对磁盘的映射——因此不算是共享内存,存储量非常大,但访问慢; shmat与此相反,通常将资源保存在内存中创建映射,访问快,但存储量较小。

不过要注意一点,操作系统并不保证任何并发问题,例如两个进程同时更改同一块内存区域,正如你和你的朋友在线编辑同一个文档中的同一个标题,这会导致一些不好的结果,所以我们需要借助信号量或其他方式来完成同步。

信号量是迪杰斯特拉最先提出的一种为解决 同步不同执行线程问题 的一种方法,进程与线程抽象来看大同小异,所以 信号量同样可以用于同步进程间通信

信号量 s 是具有非负整数值的全局变量,由两种特殊的 原子操作 来实现,这两种原子操作称为 P 和 V :

信号量并不用来传送资源,而是用来保护共享资源,理解这一点是很重要的,信号量 s 的表示的含义为 同时允许最大访问资源的进程数量 ,它是一个全局变量。来考虑一个上面简单的例子:两个进程同时修改而造成错误,我们不考虑读者而仅仅考虑写者进程,在这个例子中共享资源最多允许一个进程修改资源,因此我们初始化 s 为1。

开始时,A率先写入资源,此时A调用P(s),将 s 减一,此时 s = 0,A进入共享区工作。

此时,进程B也想进入共享区修改资源,它调用P(s)发现此时s为0,于是挂起进程,加入等待队列。

A工作完毕,调用V(s),它发现s为0并检测到等待队列不为空,于是它随机唤醒一个等待进程,并将s加1,这里唤醒了B。

B被唤醒,继续执行P操作,此时s不为0,B成功执行将s置为0并进入工作区。

此时C想要进入工作区......

可以发现,在无论何时只有一个进程能够访问共享资源,这就是信号量做的事情,他控制进入共享区的最大进程数量,这取决于初始化s的值。此后,在进入共享区之前调用P操作,出共享区后调用V操作,这就是信号量的思想。

在Linux下并没有直接的P&V函数,而是需要我们根据这几个基本的sem函数族进行封装:

正如其名,管道就如同生活中的一根管道,一端输送,而另一端接收,双方不需要知道对方,只需要知道管道就好了。

管道是一种最 基本的进程间通信机制。 管道由pipe函数来创建: 调用pipe函数,会在内核中开辟出一块缓冲区用来进行进程间通信,这块缓冲区称为管道,它有一个读端和一个写端。管道被分为匿名管道和有名管道。

匿名管道通过pipe函数创建,这个函数接收一个长度为2的Int数组,并返回1或0表示成功或者失败:

int pipe(int fd[2])

这个函数打开两个文件描述符,一个读端文件,一个写端,分别存入fd[0]和fd[1]中,然后可以作为参数调用 write 和 read 函数进行写入或读取,注意fd[0]只能读取文件,而fd[1]只能用于写入文件。

你可能有个疑问,这要怎么实现通信?其他进程又不知道这个管道,因为进程是独立的,其他进程看不到某一个进程进行了什么操作。

是的,‘其他’进程确实是不知道,但是它的子进程却可以!这里涉及到fork派生进程的相关知识,一个进程派生一个子进程,那么子进程将会复制父进程的内存空间信息,注意这里是复制而不是共享,这意味着父子进程仍然是独立的,但是在这一时刻,它们所有的信息又是相等的。因此子进程也知道该全局管道,并且也拥有两个文件描述符与管道挂钩,所以 匿名管道只能在具有亲缘关系的进程间通信。

还要注意,匿名管道内部采用环形队列实现,只能由写端到读端,由于设计技术问题,管道被设计为半双工的,一方要写入则必须关闭读描述符,一方要读出则必须关闭写入描述符。因此我们说 管道的消息只能单向传递。

注意管道是堵塞的,如何堵塞将依赖于读写进程是否关闭文件描述符。如果读管道,如果读到空时,假设此时写端口还没有被完全关闭,那么操作系统会假设还有数据要读,此时读进程将会被堵塞,直到有新数据或写端口被关闭;如果管道为空,且写端口也被关闭,此时操作系统会认为已经没有东西可读,会直接退出,并关闭管道。

对于写一个已经满了的管道同理而言。

管道内部由内核管理,在半双工的条件下,保证数据不会出现并发问题。

了解了匿名管道之后,有名管道便很好理解了。在匿名管道的介绍中,我们说其他进程不知道管道和文件描述符的存在,所以匿名管道只适用于具有亲缘关系的进程,而命名管道则很好的解决了这个问题 —— 现在管道有一个唯一的名称了,任何进程都可以访问这个管道。

注意,操作系统将管道看作一个抽象的文件,但管道并不是普通的文件,管道存在于内核空间中而不放置在磁盘(有名管道文件系统上有一个标识符,没有数据块),访问速度更快,但存储量较小,管道是临时的,是随进程的,当进程销毁,所有端口自动关闭,此时管道也是不存在的,操作系统将所有IO抽象的看作文件,例如网络也是一种文件,这意味着我们可以采用任何文件方法操作管道,理解这种抽象是很重要的,命名管道就利用了这种抽象。

Linux下,采用mkfifo函数创建,可以传入要指定的‘文件名’,然后其他进程就可以调用open方法打开这个特殊的文件,并进行write和read操作(那肯定是字节流对吧)。

注意,命名管道适用于任何进程,除了这一点不同外,其余大多数都与匿名管道相同。

消息队列亦称报文队列,也叫做信箱,是Linux的一种通信机制,这种通信机制传递的数据会被拆分为一个一个独立的数据块,也叫做消息体,消息体中可以定义类型与数据,克服了无格式承载字节流的缺陷(现在收到void*后可以知道其原本的格式惹):

同管道类似,它有一个不足就是每个消息的最大长度是有上限的,整个消息队列也是长度限制的。

内核为每个IPC对象维护了一个数据结构struct ipc_perm,该数据结构中有指向链表头与链表尾部的指针,保证每一次插入取出都是O(1)的时间复杂度。

一个进程可以发送信号给另一个进程,一个信号就是一条消息,可以用于通知一个进程组发送了某种类型的事件,该进程组中的进程可以采取处理程序处理事件。

Linux下 unistd.h 头文件下定义了如图中的常量,当你在shell命令行键入 ctrl + c 时,内核就会前台进程组的每一个进程发送 SIGINT 信号,中止进程。

我们可以看到上述只有30个信号,因此操作系统会为每一个进程维护一个int类型变量sig,利用其中30位代表是否有对应信号事件,每一个进程还有一个int类型变量block,与sig对应,其30位表示是否堵塞对应信号(不调用处理程序)。如果存在多个相同的信号同时到来,多余信号会被存储在一个等待队列中等待。

我们要理解进程组是什么,每个进程属于一个进程组,可以有多个进程属于同一个组。每个进程拥有一个进程ID,称为 pid ,而每个进程组拥有一个进程组ID,称为 pgid ,默认情况下,一个进程与其子进程属于同一进程组。

软件方面(诸如检测键盘输入是硬件方面)可以利用kill函数发送信号,kill函数接受两个参数,进程ID和信号类型,它将该信号类型发送到对应进程,如果该pid为0,那么会发送到属于自身进程组的所有进程。

接收方可以采用signal函数给对应事件添加处理程序,一旦事件发生,如果未被堵塞,则调用该处理程序。

Linux下有一套完善的函数用以处理信号机制。

Socket套接字是用与网络中不同主机的通信方式,多用于客户端与服务器之间,在Linux下也有一系列C语言函数,诸如socket、connect、bind、listen与accept,我们无需花太多时间研究这些函数,因为我们可能一辈子都不会与他们打交道,对于原理的学习,后续我会对Java中的套接字socket源码进行剖析。

对于工作而言,我们可能一辈子都用不上这些操作,但作为对于操作系统的学习,认识到进程间是如何通信还是很有必要的。

面试的时候对于这些方法我们不需要掌握到很深的程度,但我们必须要讲的来有什么通信方式,这些方式都有什么特点,适用于什么条件,大致是如何操作的,能说出这些,基本足以让面试官对你十分满意了。

不同型号的电镜有不同的更改方式,LEO电镜在file的Annotation里可以改。

SEM是一种用于电子与通信技术学科领域的仪器,主要用于所有固体材料的分析与观察,是一种介于透射电子显微镜和光学显微镜之间的一种观察手段。其利用聚焦的很窄的高能电子束来扫描样品, 通过光束与物质间的相互作用, 来激发各种物理信息, 对这些信息收集、放大、再成像以达到对物质微观形貌表征的目的。扫描电子显微镜在岩土、石墨、陶瓷及纳米材料等的研究上有广泛应用。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/76862.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-03
下一篇2023-03-03

发表评论

登录后才能评论

评论列表(0条)

    保存