使用数据库或文件作为简单的数据持久层很容易理解。但也有一些方法可以将它们用作通信通道,将数据从一个正在运行的进程传输到另一个进程,甚至发送命令和请求,特别是当这个通道比普通的 Unix 套接字更快时,比如共享内存。
但是你如何有效地使用它呢?我的意思是,一个进程不会因为共享内存的变化而获得一个事件,他总是必须轮询它,对吧?但是,如果所有进程一直在轮询它们的共享内存,这不是太耗费资源了吗?还有哪些其他选择?
使用数据库或文件作为简单的数据持久层很容易理解。但也有一些方法可以将它们用作通信通道,将数据从一个正在运行的进程传输到另一个进程,甚至发送命令和请求,特别是当这个通道比普通的 Unix 套接字更快时,比如共享内存。
但是你如何有效地使用它呢?我的意思是,一个进程不会因为共享内存的变化而获得一个事件,他总是必须轮询它,对吧?但是,如果所有进程一直在轮询它们的共享内存,这不是太耗费资源了吗?还有哪些其他选择?
为了在 Unix 或 Linux 系统上使用 IPC 获得更改通知,我可以考虑不同的技术,而无需求助于轮询。
第一次阻塞读取
可以使用文件描述符(文件、Unix 套接字、管道或命名管道、IPC 队列等)。消费者将以阻塞方式读取此文件(可能建议超时)。一旦生产者更新了共享内存,它就会向这个文件描述符写入一些东西。因此,当这种情况发生时,消费者将从读取中醒来并去读取共享内存。消费者将处于睡眠状态,因此在等待时不会消耗资源(如 CPU)。
甚至可以select
让消费者同时等待多个文件描述符。
第二个信号
消费者将被生产者发送的信号唤醒。一旦更新了共享内存,生产者就会向消费者发送一个信号(例如 SIGUSR1)。消费者之前已经订阅了信号并且可以处理请求。处理起来有点复杂,因为偶数可以随时触发,所以消费者的设计比较困难。
文件和数据库是为存储数据而设计的,并且只能将它们用于 IPC,而其他机制(互斥体、事件、信号量等)用于同步对数据的访问并发出有关更改的信号。这些机制正在被“倾听”,等待这样的信号并不消耗资源。另一方面,读取文件试图捕捉更改(这适用于内存映射文件或共享内存)既浪费资源,如果您不同步读写访问(这会让您回到互斥锁和事件等)