我从来没有真正理解为什么窗口系统必须有服务器。为什么桌面环境、显示管理器和窗口管理器需要 xorg-server?难道只是在显卡之上有一个抽象层吗?为什么窗口系统采用客户端-服务器模型?通过命名管道进行进程间通信不是更简单吗?
答案1
我想您已经注意到需要某种“服务器”。每个客户端(桌面环境、窗口管理器或窗口程序)都需要与所有其他客户端共享显示,并且它们需要能够在不知道硬件详细信息或不知道还有谁在使用该显示的情况下显示内容。因此,X11 服务器通过提供 IPC 接口来提供您提到的抽象和共享层。
X11 可能可以在命名管道上运行,但有两件大事是命名管道无法做到的。
- 命名管道仅在一个方向上进行通信。
- 如果两个进程开始将数据放入命名管道的“发送”端,则数据将混合在一起。
事实上,大多数 X 客户端使用称为 UNIX 域套接字的“新的和改进的”命名管道与服务器进行通信。它很像命名管道,只不过它允许进程双向通信,并且跟踪谁说了什么。这些都是网络必须做的事情,因此 UNIX 域套接字使用与提供网络通信的 TCP/IP 套接字相同的编程接口。
但从这里开始,很容易说“如果我在与客户端不同的主机上运行服务器怎么办?”只需使用 TCP 套接字而不是 UNIX 套接字,瞧:这是一种比 Windows RDP 早数十年的远程桌面协议。我可以ssh
连接到四个不同的远程主机并synaptic
在每个主机上运行(图形包管理器),并且所有四个窗口都显示在我的本地计算机的显示屏上。
答案2
窗口系统不一定要有服务器,但您可以决定基于客户端-服务器模型来实现窗口系统。这样做有几个优点,因为您可以清楚地分离客户端和服务器中的活动,它们不需要在同一台计算机上运行,并且更容易为多个客户端提供服务。目前这仍然非常方便(例如,当您ssh
进入另一台计算机时),但您必须意识到,在开发 X 时,这被视为必需品:您的本地计算机可能不够强大,无法运行客户端。
命名管道不会像 TCP 实现那样自动为您提供能够在网络上运行的优势。但是命名管道在 DOS 上不可用,DosExtender 运行 Desqview/X (1992),并且 AFAIK 在 VMS 上也不可用。对于这些实现,Unix 特定的通信将是一个问题。
TCP 不是特定于 Unix 的,并且可以让客户端在 VAX/VMS(X 开发于 1984 年开始)下运行,并将输出提供给基于本地 UNIX 的图形工作站。来自“X Window 系统:Xlib、X 协议、ICCCM、XLFD 的完整参考”1:
1986 年秋天,Digital 决定将其 ULTRIX、VMS 和 MS-DOS 的整个桌面工作站策略建立在 X 上。虽然这令我们感到欣慰,但这也意味着我们有更多的人可以交谈。这导致了一些延迟,但最终也带来了更好的设计。 Digital 的 Ralph Swick 在此期间加入了 Project Athena,并在版本 11 的开发过程中发挥了至关重要的作用。最后一个版本 10 于 1986 年 12 月发布。
来自“X协议参考手册”²:
职责分工
在设计X协议的过程中,我们对服务器和客户端之间的能力划分进行了很多思考,这决定了必须通过请求、回复和事件来回传递哪些信息。关于设计协议中某些选择背后的基本原理的一个极好的信息来源是由 Robert W. Scheifler 和 Jim Gettys 撰写的文章《X Window System》,该文章发表在计算机器协会杂志 Transaction on Graphics,第 5 卷,第 10 期。 1986 年 4 月 2 日 最终做出的决定是基于客户端程序的可移植性、客户端编程的简易性和性能。
首先,服务器的设计尽可能地对客户端应用程序隐藏底层硬件的差异。 ...
我记得 TOG 上的那篇文章读起来很有趣。它确实引发了我对 X 的兴趣(这是在万维网出现之前),直到 O'Reilly 开始出版他们的 X 系列书籍之前,我们很难获得更多信息。
¹ X 版本 11,第 4 版,第 2-X 页,PDF 在线提供这里
²这是我在 1990 年购买的第二版第 9 页,由 O'Reilly 出版。有较新的版本,但我从来没有费心去购买这些,而且据我所知,它们也只有纸质版。我不认为他们改变了职责分工的基本原理。
答案3
窗口系统意味着多个独立的程序共享公共资源、屏幕和输入设备。共享资源只能通过两种方式安全地实现:
- 资源可以由内核控制,应用程序可以调用内核来访问它。
- 资源可以由专用进程(服务器)控制,并且应用程序联系服务器来访问它。
当然,对实际显示硬件的访问是由内核控制的,但这对于窗口系统来说还不够:必须有一种方法可以为进程分配特定的部分可以合理地确定不会有其他进程干扰的显示(窗口),并且必须对哪些应用程序可以在何时访问资源的哪一部分提供一定程度的保护。
现在整个事情都可以进入内核,据我所知 Windows 就是这么做的。这样做的优点是速度更快(通常调用内核比联系另一个进程要快得多),但它的缺点是可能会打开安全漏洞(系统的任何漏洞都是内核级别的漏洞),同时时间限制了可移植性(在内核中实现的系统与内核强耦合;您将无法轻松地将其移植到另一个操作系统,如果您无法访问内核代码,则完全无法做到这一点)。
如果不想在内核中实现它,唯一的其他实现方式就是作为专用进程,即服务器。请注意,通过命名管道联系的服务器仍然是服务器。此外,当在同一台机器上运行时,X 服务器和客户端之间的许多通信现在都是通过共享内存进行的;但这仍然没有改变显示服务器是服务器的事实。
现在,为什么使用套接字而不是使用命名管道来联系服务器?好吧,如果您使用套接字来完成此操作,则只需为整个服务器提供一个套接字即可完成所有通信。如果您使用管道进行通信,则每个客户端需要两个管道。除了管理所有这些管道会非常麻烦之外,如果有足够多的程序尝试同时与服务器通信,您还可能会遇到操作系统对打开管道数量的限制。
当然,套接字相对于管道的另一个优点是,使用套接字可以跨机器建立连接,这在实际计算机由坐在专用终端上的许多人共享的时代尤其重要,因此计算机上的程序必须进行通信到不同的终端,但即使在今天的网络环境中它仍然非常有用。
答案4
客户端-服务器模型是一种适用于各种应用程序的流行设计,即使只有一台服务器和一个客户端也是如此。它们允许责任域之间有一个干净、定义明确的接口。
虽然服务器和客户端可以通过多种方式进行通信,但所做的选择X
(无论其他人提到的优点如何)并不是多余的:能连接到X
另一台计算机上的服务器并在桌面上(或另一个协作桌面上)打开窗口。这在 X 开发的时代非常常见,当时许多大学和企业都有 Unix 服务器和许多与之通信的“X 终端”。通过使用互联网就绪的通信协议,X 可以在主机内部或跨主机无缝使用。
X 是第一个可以透明地显示另一台计算机上的窗口的 GUI 环境,这与 UNIX 作为多用户环境而不是单台计算机上的单个用户的操作系统的历史一致。如果您是唯一能够与您的计算机进行交互(物理或远程)的人,那么许多 UNIX 功能似乎有些过大了。