0引言
嵌入式图形用户界面(Graphic User Interface)是嵌入式产品设计和开发的重点,随着嵌入式产品的广泛应用,所实现的功能也日益强大和复杂,因此对嵌入式产品的GUI在功能、易用性、稳定性等方面提出了更高的要求。目前的嵌入式GUI多是基于线程实现,在稳定性和功能上具有一定的局限性,所以开发多进程的GUI具有重要意义。
1多进程图形用户界面分析
1.1 多进程图形用户界面的优势
MiniGUI是由飞漫开发的基于事件驱动的图形用户界面支持系统,采用微C/S机制和分层设计模型,利用Unix域套接字实现客户应用程序和服务器程序之间的交互。早期的MiniGUI采用基于POSIX线程进行消息传递和窗口管理的机制,这种实现能够提供最大程度的数据共享,实现多窗口系统,但是也造成体系结构上的脆弱,所有的窗口在一个进程或者地址空间中运行,一旦某个线程因为非法的数据访问而导致崩溃或终止运行,整个图形用户界面系统都将受到影响。
在Linux系统中,任务是以进程为单位实现的。进程主要提供两类虚拟化资源:虚拟地址空间和虚拟CPU。前者保证了进程在分配和管理内存时就像机器上只有这一个进程。类似的,虚拟CPU也使进程看上去独占了CPU。 Linux系统为进程提供了安全的运行环境,保证每个进程的独立性,一个进程的崩溃不会危及其他进程。因此在多进程模式下,能够同时运行多个客户进程,如果某个进程不正常终止,其他的进程不会受到影响,因此实现多进程GUI将极大的提高系统的稳定性。
1.2 进程间通信方式的选择
基于多进程的GUI能够实现多个界面窗口的并发运行,通过进程间通信(IPC)实现窗口切换。进程间通信有多种形式,如管道、信号、共享内存等。
共享内存是由内核出于在多个进程间交互信息的目的而保留的一块内存空间,多个进程共享该内存空间,如果一个进程更新了其中的数据,其他的进程会立即看到更新,而且共享内存也是速度最快的进程间通讯机制。因此共享内存作为进程间的通信方式对于多窗口GUI系统的编程实现非常合适。
1.3 基于微C/S机制的多进程模型
对于在微C/S机制上运行的GUI系统,在运行过程中只能有一个服务器程序,其余的应用程序均为客户程序。各客户应用程序分别运行于各自不同的进程空间中,并且根据需要在应用程序之间通过进程间通信进行数据交换,完成窗口切换等过程。
MiniGUI为了实现客户端和服务器端之间的通信,定义了一种简单方便的请求/响应结构:客户程序通过制定的结构将请求发送到服务器,服务器处理请求并应答。在图形界面运行后,服务器程序完成Server端连接初始化(ServerStart()),建立服务器端连接套接字Socket,其文件描述符为listenfd,进入到侦听客户连接请求状态,用一个Idlehandler4Server句柄等待接收客户端的连接请求消息,在接受到来自于客户端的连接请求消息后进行处理,将客户应用程序加入到当前活动列表,并将客户端套接字文件描述符clifd加入到侦听文件集合中。客户端程序在完成连接初始化后(cli_conn())建立客户端套接字Socket,并发送连接请求消息给Server程序,之后采用句柄 IdelHandler4Client侦听服务器的返回消息。此后服务器程序进入一个消息循环过程,在此循环过程中继续准备接收已连接的客户程序的其他消息、新的客户程序连接请求消息以及由系统产生的鼠标、键盘事件消息等,并在事件消息处理完成后用函数Send2Client将需要的消息发送到相应的客户端应用程序。此后客户端应用程序从套接字读取由服务器程序处理后返回的消息,并把消息写到当前进程的桌面队列中,交由本进程消息循环进行分发和处理。在获得消息处理结果后用cli_quest()向服务器端发送数据请求,服务器端接收数据请求后交由handle_request按照请求功能号的不同调用不同的服务例程进行处理,完成后发送一个{HWND_INVALID,0}消息和应答数据,客户端接收服务器应答消息,至此完成一个基本的消息循环通信过程。
基于以上的分析, MiniGUI下的基于微C/S机制的多进程GUI通信模型如图1所示:
图1 基于微C/S机制的多进程通信模型
相比传统的嵌入式图形界面开发,多进程图形用户界面系统在编程实现上有较大的复杂性。图形用户界面必须实现对窗口、层、异步事件、光标或者加上触摸屏的管理,MiniGUI本身的消息机制的管理与内核系统的其他机制之间的配合等。
2图形用户界面的开发重点
2.1 图形用户界面的窗口管理
MiniGUI提供了丰富的图形构件,如窗口、对话框、控件等,能够实现各种应用功能。MiniGUI本身是基于事件驱动的图形用户界系统,所谓事件是指当用户进行窗口操作时,如移动鼠标、单击鼠标、进行键盘输入的功能,这些动作会触发一个相应的“事件”,并由支持系统收集,以特定方式翻译为消息。应用程序一般包含自己的消息队列,以接受系统消息并建立循环,这样的循环称为消息循环。消息一般由代表消息类型的数和附加参数构成。
多窗口系统在屏幕上要同时显示多个应用程序窗口,程序窗口之间会有相互重叠关系。所以GUI系统运行后首先要创建一个根窗口,此窗口在系统启动时由启动脚本运行,是所有其他窗口的依附窗口。其他子窗口由用户在根窗口内点击相应图标产生,并且在子窗口内可以继续派生出自己的下一级子窗口,每个子窗口拥有一个窗口ID号,以标示与上级窗口的派生关系,据此便可以追溯到根窗口,而不至于产生窗口管理的混乱。窗口之间的可以为同级或者上下级派生关系。相互间的逻辑结构如图2所示:
图2 窗口关系逻辑框图