WEB开发网
开发学院软件开发Shell 将OS/2应用程序移植到Linux(2) 阅读

将OS/2应用程序移植到Linux(2)

 2009-06-30 03:14:00 来源:WEB开发网   
核心提示:作者:Kevin Bowkett 实现一个与 OS/2 (它进行一些边界检查)类似的行为的另一个方法是使用文件映射,文件映射将一个文件映射到一个进程的内存空间内,将OS/2应用程序移植到Linux(2),以便允许把文件像内存一样来访问,没必要整个文件映射到内存,Kevin 还是一名获 IBM 认证的 DB2 应用

  作者:Kevin Bowkett
  
  实现一个与 OS/2 (它进行一些边界检查)类似的行为的另一个方法是使用文件映射。文件映射将一个文件映射到一个进程的内存空间内,以便允许把文件像内存一样来访问。没必要整个文件映射到内存,但可以把文件的一部分映射到一个内存区域。
  
  共享内存机制的另一个差别是:当一个段被加载到一个进程中时,Linux 不保证会使用相同的内存地址。在 OS/2 上,您可以分配一块内存并将这一块内存传送给另一个进程。内存位于每个进程中相同的地址处。在 Linux 上情况并不一定如此。另外,为了访问另一个进程已创建的一个共享内存段,您需要知道这个段的标识。标识是一个独一无二的数字,可以通过使用一个名称(如果该名称作为一个文件存在)来计算这个数字。OS/2 提供几个系统调用,使得进程能够给出且获得到基于名字或内存地址的共享内存段的访问。
  
  队列
  
  OS/2 队列是一个允许进程把内存指针传给另一个进程的机制。传送进程必须通过 DosGiveSharedMemory 给接受进程提供到内存段的访问,然后把内存在段中的位置传送给接收进程。像机制名暗示的一样,队列可以在等待另一个进程读取它们的同时保存大量的这些内存位置。Linux 没有这个概念。
  
  在可能的解决方案中,其中之一就是使用 System V 共享内存段。System V 共享内存段的问题是限制了被允许的段的数量。
  
  另一个方法是使用文件映射并使用控制结构,该结构设置元素(内存位置)的顺序和对文件的访问权限。
  
  信号量(Semaphore)
  
  OS/2 提供三种主要类型的信号量:事件、互斥和多等待。Linux 提供一个基于 System V IPC 的信号量机制并且支持信号量作为 pthread 库的一部分。OS/2 信号量是一个单独的实体,给您提供一个定义良好的行为。然而,可以将 System V 信号量定义成几组,这是可配置的。在不重新编译内核的情况下,每个组最多可以有 250 个信号量(2.4 内核)。这种系统在系统内只能有一定数量的信号量组(可以通过重编译内核来更改这个数量)。
  
  System V 信号量基本上是计数变量,您可以增加或减少这些变量,并且这为您模仿事件信号量和互斥信号量的行为提供了足够的功能。唯一的问题是执行定时等待。在 Linux 上,您只能尝试/等待或等待。不允许超时。为了模仿超时,您需要构建某种定时机制,该机制能发送一个信号来中断正在等待一个事件的线程。
  
  多等待信号量是一个已定义信号量的集合,这些信号量可以作为一组等待。System V 机制利用组,并且能等待许多与同一个组相关的操作。然而,只有应用程序仔细地规划了它对信号量(多等待中的所有信号量都来自于同一个信号量组)的使用,您才能得到期望的结果。我们实现了一个机制,它使线程能够等候这组内的每个信号量来模拟这一行为。
  
  pthread 库提供了能合理模仿 OS/2 行为的信号量和互斥(以及条件变量)。然而,还存在缺陷。请注意,pthread 信号量和互斥是不可共享的。换言之,仅在那个进程中保证它们。如果您的应用程序仅使用私有信号量,或者如果没有其它进程需要访问它的信号量,那么使用 pthread 互斥和信号量可能是最好的计划。但是,如果您的应用程序共享这些 IPC 机制,那么您需要用 System V 机制、共享内存和线程来实现这些机制。
  
  信号
  
  在OS/2上,为了指明某些错误情况,要抛出异常。在 Linux 上,这些被称为信号。与异常一样,除了 SIGKILL 和 SIGSTOP 之外,信号都可以被捕获。在 OS/2 上,您可以定义一列在接收到异常时需要执行的函数。应用程序可以在 OS/2 上定义不止一个异常处理程序。在 Linux 上,因为函数被覆盖了,所以您只能定义一个异常处理程序。
  
  管道
  
  在 OS/2 上,管道是双向的,而 Linux 上的管道是单向的。为了模仿 OS/2 管道的行为,您需要创建两个管道,通过一个文件句柄来索引。
  
  共享对象
  
  Linux共享对象和DLL非常相似,但是需要注意几个陷阱。应用程序可以在一个共享对象中重写函数。如果一个共享对象有 print_hello 函数并且应用程序有一个叫作 print_hello 的函数,那么无论何时应用程序调用 print_hello,都使用应用程序的版本。您在共享对象中调用一个函数之前(例如,so_print 调用 print_hello),这可能听上去不像什么问题。这种情况中使用的 print_hello 是应用程序中定义的那个。
  
  感觉上的标准函数
  
  您在作关于标准 C 函数方面的假设时应该谨慎一些。例如,kbhit 和 strupr 不是标准函数。尽管它们可能是一个编译器的 C 标准库的一部分,但是假定这些函数和其它函数存在于所有平台上是不安全的。
  
  
  结束语
  
  
  前面所述的差别无论如何不包含一个确定的列表。这样一个列表中包含的信息足够写一本书了。然而,当您将一个应用程序从 OS/2 移植到 Linux 上时,这些差别应该使您可以提前找到需要解决问题的地方。
  
  LANDP for Linux 小组设计了一个映射层来帮助我们从 OS/2 向 Linux 移植。映射层是一个共享对象,用于从 OS/2 移植各个 LANDP 服务器。可能映射层将为其它项目提供一个起点,也许不会提供。
  
  关于作者
  
  Kevin Bowkett 是一名在 LANDP 开发组中工作的 IBM 软件工程师,在 Linux、Windows 和 OS/2 操作系统方面有很好的基础。在过去的一年中,Kevin 带领 LANDP 小组将 LANDP for Linux 投入了市场。Kevin 还是一名获 IBM 认证的 DB2 应用开发解决方案专家。如果您正在从事从 OS/2 到 Linux 的移植并且有什么问题的话,可以和他联系。
  
  『引自 IBM DW中国』
 

Tags:OS 应用程序 移植

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接