是否可以使用一个unix进程来控制多个终端?

是否可以使用一个unix进程来控制多个终端?,unix,terminal,ncurses,Unix,Terminal,Ncurses,因此,我所熟悉的典型模型是,如果您想让不同终端上的多个用户通过某种方式与同一进程交互,那么您可以编写与单个服务器进程交互的客户端程序 我的问题是:每个客户端是否可能/合理地以某种方式直接连接到单个进程,而不必编写客户端/服务器程序?我的目标是避免套接字层序列化的复杂性,让所有终端使用内存中的共享数据结构进行通信 我猜这将是相当棘手的,在unix下可能是不可能的,但我想听听是否有人做过或见过类似的事情,可能的要求是什么,以及这种方法的其他缺点是否超过了序列化复杂性的降低。我想颠倒观点:“让每个客户

因此,我所熟悉的典型模型是,如果您想让不同终端上的多个用户通过某种方式与同一进程交互,那么您可以编写与单个服务器进程交互的客户端程序

我的问题是:每个客户端是否可能/合理地以某种方式直接连接到单个进程,而不必编写客户端/服务器程序?我的目标是避免套接字层序列化的复杂性,让所有终端使用内存中的共享数据结构进行通信


我猜这将是相当棘手的,在unix下可能是不可能的,但我想听听是否有人做过或见过类似的事情,可能的要求是什么,以及这种方法的其他缺点是否超过了序列化复杂性的降低。

我想颠倒观点:“让每个客户端以某种方式直接连接到单个进程”在unix中是一种胡说八道(不仅如此),即使您不想使用套接字,也必须编写一个“客户端”附加到服务器发布的共享内存对象、命名管道甚至普通文件的程序。用于与服务器通信的介质可能有所不同,但通常unix的体系结构鼓励将“服务器”功能分配给单独的进程(或更多进程)。因此,您可能想要的是一种“轻松”的进程间通信,对等方之间很少或没有仲裁。如果数据完整性没有问题,您可以使用服务器公开的共享内存块,其中所有客户端(是的,您必须编写“客户端”程序)都可以作为普通内存块连接到读取数据。 如果您需要某种数据完整性,或者如果客户端有时还需要向共享内存写入某些内容,那么可以使用信号量或互斥来同步对共享块内数据结构的访问。这个解决方案有很多缺点,只有当“共享数据库”不经常更改,或者数据完整性不是一个要求,或者互斥/信号量导致的开销是可以接受的时候,它才有意义

为了完整起见,我将讲述我们在串行终端的好时光是如何习惯的:在那个时候,服务器进程本身直接处理许多终端。只需打开终端线路(一个或多个/dev/ttyXXX设备),对其进行配置,并拥有一个“主循环”,其中每个通道(即文件描述符)都由“选择”系统调用或类似调用监听。当然,终端被锁定到特定的应用程序,用户只能做应用程序允许他/她做的事情


编辑:避免编写客户端程序的一种常见方法是使服务器在tcp端口上实现一个简单的基于文本、面向行的协议。客户是。。。telnet!当然,这是一个非常粗鲁的解决方案,但在许多情况下(例如调试、维护等),这已经足够了。

您自己找到了答案!您可以使用共享内存段进行进程通信
shm_open
是POSIX共享段的一个很好的入口,您还可以使用
shmget
SYSV共享段,甚至
mmap
共享内存映射


当然会有一些棘手的部分,因为您需要清楚地定义共享结构是如何共享的。通常使用某种信号量或类似的东西来同步对结构的访问。而且可能不会让您不再需要定义一种协议/序列化…

终端仿真器已经是客户端了。只需打开tty文件

例子
正确的!但是一个进程只能控制(在Unix意义上)一个终端。当然,一个进程可以读/写许多不同的术语,但不能控制所有术语。是的,在unix的体系结构中,一个进程可能只属于一个进程组(基本上是一个终端会话,可以,有点),但这并不禁止该进程自由管理更多的行。实际上,说进程控制其会话终端是不正确的,相反,会话终端控制其进程组中的进程。好的,但每个进程只能有一个控制终端。不管怎样,也许从一个过程中管理不同的术语就足够了……正确。请考虑,“控制终端”(如果有的话——一个进程也可以运行,而没有任何控制终端,如系统守护进程),管理许多终端的应用程序通常具有特殊功能(例如,管理、调试…)。
$ gnome-terminal --tab-with-profile=main --command="env sleep 1d" --tab-with-profile=main --command="env sleep 1d"
$ ps --ppid $PPID -ly
S   UID   PID  PPID  C PRI  NI   RSS    SZ WCHAN  TTY          TIME CMD
S  1000  2151  2082  0  80   0  5208  2200 wait   pts/1    00:00:02 bash
...
S  1000  4500  2082  0  80   0   284  1051 hrtime pts/8    00:00:00 sleep
S  1000  4501  2082  0  80   0   280  1051 hrtime pts/9    00:00:00 sleep
$ echo -e 'tab1: \e[31mWorking!\e[39m' > /dev/pts/8
$ echo -e 'tab2: \e[31mWorking!\e[39m' > /dev/pts/9