让一个软件进程与另一个软件进程对话是一项微妙的平衡行为。 然而,对于应用程序来说,这可能是一项至关重要的功能,因此任何开始复杂项目的程序员都必须解决这个问题。 无论您的应用程序是否需要启动由其他人的软件处理的作业; 监控外围设备或网络执行的操作; 或者检测来自其他来源的信号,当您的软件依赖于自身代码之外的东西来知道下一步该做什么或何时执行时,您都需要考虑进程间通信 (IPC)。
Unix 操作系统很久以前就考虑到了这一点,可能是因为早期期望软件会来自不同的来源。 按照同样的传统,Linux 提供了许多相同的 IPC 接口和一些新的接口。 Linux 内核具有多种 IPC 方法,并且 util-linux 软件包 包含 ipcmk、ipcrm、ipcs 和 lsipc 命令,用于监控和管理 IPC 消息。
显示 IPC 信息
在尝试 IPC 之前,您应该了解您的系统上已有哪些 IPC 工具。 lsipc 命令提供该信息。
RESOURCE DESCRIPTION LIMIT USED USE%
MSGMNI Number of message queues 32000 0 0.00%
MSGMAX Max size of message (byt.. 8192 - -
MSGMNB Default max size of queue 16384 - -
SHMMNI Shared memory segments 4096 79 1.93%
SHMALL Shared memory pages 184[...] 25452 0.00%
SHMMAX Max size of shared memory 18446744073692774399
SHMMIN Min size of shared memory 1 - -
SEMMNI Number of semaphore ident 32000 0 0.00%
SEMMNS Total number of semaphore 1024000.. 0 0.00%
SEMMSL Max semaphores per semap 32000 - -
SEMOPM Max number of operations p 500 - -
SEMVMX Semaphore max value 32767 - -
您可能会注意到,此示例列表包含三种不同类型的 IPC 机制,每种机制在 Linux 内核中都可用:消息 (MSG)、共享内存 (SHM) 和信号量 (SEM)。 您可以使用 ipcs 命令查看每个子系统的当前活动
$ ipcs
------ Message Queues Creators/Owners ---
msqid perms cuid cgid [...]
------ Shared Memory Segment Creators/Owners
shmid perms cuid cgid [...]
557056 700 seth users [...]
3571713 700 seth users [...]
2654210 600 seth users [...]
2457603 700 seth users [...]
------ Semaphore Arrays Creators/Owners ---
semid perms cuid cgid [...]
这表明当前没有消息或信号量数组,但正在使用许多共享内存段。
有一个简单的示例您可以在系统上执行,以便您可以看到其中一个系统正在工作。 它涉及一些 C 代码,因此您的系统上必须有构建工具。 您必须安装才能从源代码构建的软件包名称因您的发行版而异,因此请参阅您的文档以获取具体信息。 例如,在基于 Debian 的发行版上,您可以了解 wiki 的 BuildingTutorial 部分的构建要求,在基于 Fedora 的发行版上,请参阅文档的 从源代码安装软件 部分。
创建消息队列
您的系统已经有一个默认消息队列,但您可以使用 ipcmk 命令创建自己的消息队列
$ ipcmk --queue
Message queue id: 32764
编写一个简单的 IPC 消息发送器,为了简单起见,硬编码队列 ID
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
struct msgbuffer {
char text[24];
} message;
int main() {
int msqid = 32764;
strcpy(message.text,"opensource.com");
msgsnd(msqid, &message, sizeof(message), 0);
printf("Message: %s\n",message.text);
printf("Queue: %d\n",msqid);
return 0;
}
编译应用程序并运行它
$ gcc msgsend.c -o msg.bin
$ ./msg.bin
Message: opensource.com
Queue: 32769
您刚刚向消息队列发送了一条消息。 您可以使用 ipcs 命令进行验证,使用 --queue 选项将输出限制为消息队列
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x7b341ab9 0 seth 666 0 0
0x72bd8410 32764 seth 644 24 1
您还可以使用以下命令检索这些消息
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
struct msgbuffer {
char text[24];
} message;
int main() {
int msqid = 32764;
msgrcv(msqid, &message, sizeof(message),0,0);
printf("\nQueue: %d\n",msqid);
printf("Got this message: %s\n", message.text);
msgctl(msqid,IPC_RMID,NULL);
return 0;
编译并使用以下命令运行
$ gcc get.c -o get.bin
$ ./get.bin
Queue: 32764
Got this message: opensource.com
下载 电子书
这只是 Marty Kalin 的 Linux 进程间通信指南 中提供的课程示例之一,这是 Opensource.com 最新的免费(和知识共享)可下载电子书。 在短短几节课中,您将了解来自消息队列、共享内存和信号量、套接字、信号等的 POSIX IPC 方法。 坐下来阅读 Marty 的书,您将成为一位更博学的程序员。 但它不仅仅适用于经验丰富的程序员——如果您只编写 shell 脚本,那么关于管道(命名管道和匿名管道)和共享文件,以及在使用共享文件或外部消息队列时需要了解的重要概念,也有大量的实用知识。
如果您有兴趣制作出色的动态且系统感知的软件,您需要了解 IPC。 让 本书 成为您的指南。
评论已关闭。