有我有你,测试变得更完美.......

发布新日志

  • 《转》关于进程间通信的学习心得

    2009-02-11 12:18:41

    进程:进程是指独立地址空间的指令序列

    进程的五种状态:新建,就绪,运行,睡眠,僵死

    进程间通信:是不同进程之间进行一些"接触",这种接触有简单,有复杂。机制不同,复杂度也不同。通信是一个广义上的意义,不仅指大批量数据传送,还包括控制信息的传送,但使用方法是基本相同的。

    基本的进程通信机制

    1.传统UNIX-IPC机制:信号和管道

    2.SystemVIPC机制:共享内存、信号量和消息队列

    3.起源于Unix BSD版本的套结字(Socket

    4.远程过程调用(RPC

     信号:Unix系统中使用的最古老的进程间通讯的方法之一,用于向一个或多个进程发送异步事件的信号。信号可以类比于DOS下的INT或者是Windows下的事件。在有一个信号发生的时候,相应的信号就会发送给相应的进程。

    信号机制的实现

    1.信号包括待处理信号和被阻塞信号

    2.如果产生了一个被阻塞的信号,它一直保留待处理,直到被解除阻塞。

    3.系统保存每一个进程如何处理每一种可能的信号的信息。

    4.系统判断进程是希望忽略这个信号还是让内核处理。进程通过执行系统调用改变缺省的信号处理 

    对信号的处理

    1.初始化信号集,只有在信号集里面的信号才会被考虑

    2.安装信号处理器。所谓信号处理器,就是指定了一些对信号的处理方法。在安装的时候,一定要对特定的信号赋予正确的信号处理函数。

    信号相关函数

    int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);为进程安装信号处理器,struct sigaction数据结构是用来保存信号处理器的相关信息。

    int sigemptyset(sigset_t *set);将信号集合清空。

    int sigfillset(sigset_t *set);将信号集合设置成包含所有的信号,在对信号进行操作以前一定要对信号集进行初始化。

    int sigaddset(sigset_t *set, int signo);向信号集中加入signo对应的新信号。

    int sigdelset(sigset_t *set, int signo);从信号集中删除signo对应的一个信号。

    int sigismember(const sigset_t *set, int signo);判断某个信号是否在信号集中。

    int sigprocmask(int how,const sigset_t *set, sigset_t *oset);设置进程的信号屏蔽码。信号屏蔽码可以用来在某段时间内阻塞一些信号集中的信号。

    管道通信:是最古老的Unix IPC工具,一个进程从管道一头写数据,另一个进程从管道另一头读数据,以实现它们之间通信的共享方式,又称pipe文件。由于发送和接收都是利用管道进行通信的,故称为管道通信。通信方式是单向的。管道类型分为:无名管道、命名管道

    管道通信的思想

    1.发送进程可以源源不断的从pipe一端写入数据流,在规定的pipe文件的最大长度(如4096字节)范围内,每次写入的信息长度是可变的。

    2.接收进程在需要时可以从pipe的另一端读出数据,读出单位长度也是可变的。

    基本管道调用函数

    int do_pipe(int *fd);创建管道

    static int pipe_release(struct inode *inode, int decr, int decw);管道释放

    无名管道II

    显示了每一个file数据结构包含了不同的文件操作例程的向量表的指针:一个用于写,另一个从管道中读。这掩盖了和通用的读写普通文件的系统调用的不同。当写进程向管道中写的时候,字节拷贝到了共享的数据页,当从管道中读的时候,字节从共享页中拷贝出来。

    命名管道:又名FIFO,它不是临时的对象,而是文件系统中的实体,可以用mkfifo命令创建。系统必须处理在写进程打开FIFO之前打开FIFO读的进程,以及在写进程写数据之前读的进程。它使用和无名管道一样的数据结构和操作。

            (写入端)[Fd1]pipe(fd)[Fd0] (读出端)

     信号量:信号量(Semaphore)和信号是不同的东西,信号是实现约定的固定的值,而信号量是一个变量记录着某些特定信息,它的使用主要是用来保护共享资源,使得该资源在一个时刻只让一个进程拥有。

    信号量的数据结构:使用semid_ds数据结构表达信号量。系统中所有的semid_ds数据结构都由semary指针向量表指向。每一个信号灯数组中都有sem_nsems,通过sem_base指向的一个sem数据结构来描述

    信号量机制的实现

    1.对信号量的操作只有两个:PV

    2.为了在逻辑上便于组织信号量,信号量机制中有一个概念是信号量组。我们在一个信号量组中创建相关的信号量,这样逻辑上清晰也便于管理。

    3.在使用之前同样需要对他们进行初始化:生成或打开信号量组,向其中生成或删除指定的信号量。

    4.一个信号量必须属于一个信号量组,否则不能被系统所使用。

    5.信号量和信号量组是不会被系统所自动清理的,所以在进程退出前,需要及时清理生成的那些信号量。

    信号量的相关函数

     int semget(key_t key, int nsems, int semflg) 创建一个新的信号量组或获取一个已经存在的信号量组。

    int semop(int semid, struct sembuf *sop, int nsops);一次对一个或多个信号量进行操作,用于PV操作。

    Int semctl(int sem_id, int semnum, int cmd, union semun arg);用来获取一些信号量的使用信息或者是来对信号量进行控制。

    共享内存

         共享内存是进程通信的一个重要方法,为进程提供了直接通信的手段。操作系统中一个或多个进程通过同时出现在它们的虚拟地址空间的内存通讯,该虚拟内存被每个共享进程的页表所引用,它们的地址无需相同。进程对共享内存的访问是受控的,信号量等机制实现了共享内存访问的同步

    共享内存的简单原理

    每一个新创建的内存区域都用一个shmid_ds数据结构来表达。这些数据结构保存在shm_segs向量表中。Shmid_ds数据结构描述了这个共享内存取有多大、多少个进程在使用它以及共享内存如何映射到它们的地址空间。由共享内存的创建者来控制对于这块内存的访问权限和它的key是公开或私有。如果有足够的权限它也可以把共享内存锁定在物理内存中。每一个希望共享这块内存的进程必须通过系统调用粘附(attach)到虚拟内存。这为该进程创建了一个新的描述这块共享内存的vm_area_struct数据结构。进程可以选择共享内存在它的虚拟地址空间的位置或者由Linux选择一块足够的的空闲区域。这个新的vm_area_struct结构放在由shmid_ds指向的vm_area_struct列表中。通过vm_next_sharedvm_prev_shared把它们连在一起。

    共享内存的基本函数

     int shmget(key_t key,int size,int shmflg);建立新的共享内存或一个已存在的共享内存描述字

    void *shmat(int shmid,const void *shmaddr,int shmflg);将物理共享内存粘附到进程虚拟地址空间

    int shmdt(const void *shmaddr);进程从其虚拟地址空间分离共享内存

    int shmctl(int shmid,int cmd,struct shmid_ds *buf);查询及设置一个共享内存

    共享内存机制的实现

    在使用一个共享内存之前我们调用shmat得到共享内存的开始地址,使用结束以后我们使用

    shmdt断开这个内存。

    进程通过系统调用粘附到虚拟内存,即创建了一个新的描述这块共享内存的vm_area_struct数据结构,这个新的vm_area_struct结构放在由shmid_ds指向的vm_area_struct列表中。通过vm_next_sharedvm_prev_shared把它们连在一起。

    虚拟内存在粘附的时候其实并没有创建,而发生在第一个进程试图访问它的时候。

    第一个访问共享内存页的进程使得这一页被创建,而随后访问的其他进程使得此页被加到它们的虚拟地址空间。

    当进程不再需要共享虚拟内存的时候,它们从中分离出来。只要仍旧有其他进程在使用这块内存,这种分离只是影响当前的进程。

    当共享这块内存的最后一个进程从中分离出的时候,共享内存当前在物理内存中的页被释放

    消息队列 消息队列是比较高级的一种进程间通信方法,实现一个或多个进程间message传送,一个消息队列可以被多个进程所共享(IPC就是在这个基础上进行的);如果一个进程的消息太多一个消息队列放不下,也可以用多于一个的消息队列(不过可能管理会比较复杂)。

    消息队列的基本函数

    int msgget(key_t key, int msgflg);获取一个存在的消息队列的ID,或者是根据跟定的权限创建一个消息队列。

    int msgctl(int msqid, int cmd, struct msqid_ds *buf);用来从msqid_ds中获取很多消息队列本身的信息。

    int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg);用于向队列发送消息。

    int msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, intmsgflg) 从队列中接收消息。

    消息队列的实现机制

    消息队列,是一个队列的结构,队列里面的内容由用户进程自己定义。实际上,队列里面记录的是指向用户自定义结构的指针和结构的大小。要使用message queue,首先要通过系统调用(msgget)产生一个队列,然后,进程可以用msgsnd发送消息到这个队列,消息就是如上所说的结构。别的进程用msgrcv读取。消息队列一旦产生,除非明确的删除(某个有权限的进程或者用ipcrm命令)或者系统重启。否则,产生的队列会一直保留在系统中。而且,只要有权限,就可以对队列进行操作。消息队列和管道很相似,实际上,管道就是用户消息为1个字节的队列。

    消息队列的写进程

    每一次一个进程试图向写队列写消息,它的有效用户和组的标识符就要和队列的ipc_perm数据结构的模式比较。如果进程可以想这个队列写,则消息会从进程的地址空间写到msg数据结构,放到消息队列的最后。每一个消息都带有进程间约定的,应用程序指定类型的标记。

    消息队列的读进程

     从队列中读是一个相似的过程。进程的访问权限一样被检查。一个读进程可以选择是不管消息的类型从队列中读取第一条消息还是选择特殊类型的消息。如果没有符合条件的消息,读进程会被加到消息队列的读等待进程,然后运行调度程序。当一个新的消息写到队列的时候,这个进程会被唤醒,继续运行。

    消息队列的简单流程

    发送进程                              接收流程

    Send(m)                               Receive(m )

        Begin                                  begin

        向系统申请一个消息缓冲区               P(SM)  等待接的消息的个数

        P(mutex)  使用公用缓冲区                P(mutex)  使用公用缓冲区

        将发送区消息m送入新申请的消息缓冲区   摘下消息队列中的消息m

        把消息缓冲区挂入接收进程的消息队列      将消息队列m从缓冲区复制到接收区

        V(mutex) 释放缓冲区                     释放缓冲区

        V(SM) 向接收进程发送消息               V(mutex)  释放公用缓冲区

        End                                      end

    Socket

     独立于具体协议的网络编程接口;

    ISO模型中,主要位于会话层和传输层。

    网络编程接口:UNIX BSD的套接字(socket)、UNIX System VTLI

    BSD Socket(伯克立套接字)是通过标准的UNIX文件描述符和其它程序通讯的一个方法,目前已经被广泛移植到各个平台。

    Socket的类型

     流式套接字:提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复地发送且按发送顺序接收.内设流量控制,避免数据流超限;数据被看作是字节流,无长度限制,FTP即用此

    数据报套接字:提供了一个无连接服务.数据包以独立包形式被发送,不提供无差错保证,数据可能丢失或重复,并且接受顺序无序,网络文件系统NFS

    原始套接字(SOCK_RAW):该接口允许对较低层次协议,如IP,ICMP直接访问

    基本套接字调用

    创建套接字                socket()

    绑定本机端口            bind()

    建立连接                    connect()

    接受连接                    accept()

    监听端口                    listen()

    数据传输                    send(), recv()

    关闭套接字                close();

    Socket相关数据结构

    struct sockaddr_in

               {

                       short int          sin_family;     /*通信类型*/

                       unsigned short int  sin_port;        /*端口号,网络直接顺序*/

                       struct in_addr   查看(759) 评论(1) 收藏 分享 管理

  • 转:嵌入式系统测试方法研究

    2009-01-16 14:45:46

      前言

      软硬件结合的嵌入式系统正越来越多的应用到我们的日常生活中,参予嵌入式系统的研究和开发的开发商也越来越多,从而第三方测试人员会经常接触到嵌入式系统测试。因此需要第三方测试人员了解嵌入式系统的特性,把握其测试方法。虽然现在有不少与嵌入式系统测试相关的资料,但这些资料都是以第二方测试的角度去讨论的,如何从第二方的测试经验中提取有用经验,结合第三方测试特点,研究出适合第三方测试使用的嵌入式系统测试方法,正是这一课题的意义所在。

      一、嵌入式系统介绍

      嵌入式系统是以应用为中心,以计算机技术为基础,并且软硬件可裁剪,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。它一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用户的应用程序等四个部分组成,用于实现对其他设备的控制、监视或管理等功能。

      嵌入式系统一般指非PC系统,它包括硬件和软件两部分。硬件包括处理器/微处理器、存储器及外设器件和I/O端口、图形控制器等。软件部分包括操作系统软件(OS)(要求实时和多任务操作)和应用程序编程。有时设计人员把这两种软件组合在一起。应用程序控制着系统的运作和行为;而操作系统控制着应用程序编程与硬件的交互作用。

      嵌入式系统的核心是嵌入式微处理器。嵌入式微处理器一般就具备以下4个特点:

      ◆ 对实时多任务有很强的支持能力,能完成多任务并且有较短的中断响应时间,从而使内部的代码和实时内核心的执行时间减少到最低限度。

      ◆ 具有功能很强的存储区保护功能。这是由于嵌入式系统的软件结构已模块化,而为了避免在软件模块之间出现错误的交叉作用,需要设计强大的存储区保护功能,同时也有利于软件诊断。

      ◆ 可扩展的处理器结构,以能最迅速地开展出满足应的最高性能的嵌入式微处理器。

      ◆ 嵌入式微处理器必须功耗很低,尤其是用于便携式的无线及移动的计算和通信设备中靠电池供电的嵌入式系统更是如此,如需要功耗只有mW甚至μW级。

      嵌入式计算机系统同通用型计算机系统相比具有以下特点:

      ◆ 高可靠性——可靠性主要有两个方面含义:a)硬件本身要连续稳定运行;b)系统检查出故障后要有保持安全状态的能力。虽然硬件抗干扰技术可在一定程度上提高嵌入式系统的可靠性,但是系统的可靠性仍然决定着嵌入式系统的安全运行。

      ◆ 实时性——实时性指系统对响应时间的严格要求,指能在确定的时间内执行其功能,能对外部的异步事件做出快速正确的响应。它分为硬实时和软实时两种,前者意味着存在必须满足的时间限定,在不满足响应时限、响应不及时或响应过早得情况下都会导致灾难性的后果;后者则表示时限并非那么严格,偶尔超过时限限制是可以容忍的,只是导致系统性能退化,不会造成灾难性后果。

      ◆ 嵌入式系统通常是面向特定应用的,嵌入式CPU与通用型的最大不同就是嵌入式CPU大多工作在为特定用户群设计的系统中,它通常都具有低功耗、体积小、集成度高等特点,能够把通用CPU中许多由板卡完成的任务集成在芯片内部,从而有利于嵌入式系统设计趋于小型化,移动能力大大增强,跟网络的耦合也越来越紧密。

      ◆ 嵌入式系统是将先进的计算机技术、半导体技术和电子技术与各个行业的具体应用相结合后的产物。这一点就决定了它必然是一个技术密集、资金密集、高度分散、不断创新的知识集成系统。

      ◆ 嵌入式系统的硬件和软件都必须高效率地设计,量体裁衣、去除冗余,力争在同样的硅片面积上实现更高的性能,这样才能在具体应用中对处理器的选择更具有竞争力

      ◆ 嵌入式系统和具体应用有机地结合在一起,它的升级换代也是和具体产品同步进行,因此嵌入式系统产品一旦进入市场,具有较长的生命周期。

      ◆ 为了提高执行速度和系统可靠性,嵌入式系统中的软件一般都固化在存储器芯片或单片机本身中,而不是存贮于磁盘等载体中。

      ◆ 嵌入式系统本身不具备自举开发能力,即使设计完成以后用户通常也是不能对其中的程序功能进行修改的,必须有一套开发工具和环境才能进行开发。

      二、嵌入式系统测试

      嵌入式系统测试/嵌入式测试或叫交叉测试(cross-test)的目的与非嵌入式软件是相同的,都是为了查找软件潜在的缺陷。但在嵌入式系统设计中,软件正越来越多地取代硬件,以降低系统的成本,获得更大的灵活性,这就需要使用更好的测试方法和工具进行嵌入式和实时软件的测试。

      针对嵌入式系统的测试种类有:模块测试、集成测试、系统测试、硬件/软件集成测试,验收和确认测试。

      作为第三方测试,我们重点关注系统验收测试和确认测试。

      ……………………

    查看全文请点击下载:http://www.51testing.com/html/200901/n101614.html

Open Toolbar