0Pricing
C Academy · 课时

共享内存

快速 IPC

共享内存 是 CoddyKit 上的免费 C Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C Academy 课程共包含 4 节课。

使用共享内存实现快速 IPC

共享内存允许多个进程将同一块物理内存区域映射到各自的地址空间中。它是最快的 IPC 形式,因为数据不需要经过内核复制。

快速的原因

管道和套接字会将数据从一个进程复制到内核,再复制回来。共享内存跳过了这一过程:完成映射后,各进程直接读写同一批字节,每条消息都无需复制。

POSIX 与 System V

有两套 API:

  • POSIX:shm_open + mmap,类似文件且较为现代
  • System V:shmget + shmat,较旧,基于键值

对于新代码,通常更推荐 POSIX。

第 1 步:创建对象

shm_open 会创建或打开一个命名共享内存对象,并返回一个文件描述符。名称以斜杠开头,例如 /myshm。

#include <sys/mman.h>
#include <fcntl.h>

int create_shm(const char *name) {
    int fd = shm_open(name, O_CREAT | O_RDWR, 0666);
    return fd; /* -1 on error */
}

第 2 步:设置大小

新创建的共享对象长度为零。请在映射前使用 ftruncate 设置其大小。

#include <unistd.h>
#include <stddef.h>

int size_shm(int fd, size_t bytes) {
    return ftruncate(fd, (off_t)bytes); /* set the region size */
}

第 3 步:进行映射

mmap 会将对象映射到进程的地址空间,并返回一个指针;您可以像使用普通内存一样使用它。

#include <sys/mman.h>
#include <stddef.h>

void *map_shm(int fd, size_t bytes) {
    void *p = mmap(NULL, bytes, PROT_READ | PROT_WRITE,
                   MAP_SHARED, fd, 0);
    return p; /* MAP_FAILED on error */
}

读取与写入

完成映射后,只需解引用该指针即可。共享内存中的结构体对所有映射了同一对象的进程都可见。

#include <string.h>

typedef struct { int counter; char text[64]; } Shared;

void producer(Shared *s) {
    s->counter = 42;
    strcpy(s->text, "hello from producer");
}

MAP_SHARED 至关重要

您必须传入 MAP_SHARED,这样写入内容才能对其他进程可见。MAP_PRIVATE 会创建写时复制的私有映射,其他进程永远看不到其中的修改。

同步由您负责

共享内存不提供内置同步机制。如果没有协调,两个进程可能在竞争条件下破坏数据。请使用信号量、互斥锁或原子操作来保护共享内存。

使用命名信号量

POSIX 命名信号量(sem_open)可以协调访问。producer 在数据准备好后执行 post;consumer 在读取前执行 wait。

#include <semaphore.h>
#include <fcntl.h>

sem_t *open_sem(const char *name) {
    return sem_open(name, O_CREAT, 0666, 0); /* initial value 0 */
}
/* producer: sem_post(s);   consumer: sem_wait(s); */

清理资源

请始终释放资源:

  • 使用 munmap 取消区域映射
  • 使用 close 关闭描述符
  • 使用 shm_unlink 删除命名对象

否则,进程退出后该对象仍会留在 /dev/shm 中。

#include <sys/mman.h>
#include <unistd.h>
#include <stddef.h>

void cleanup(void *p, size_t bytes, int fd, const char *name) {
    munmap(p, bytes);
    close(fd);
    shm_unlink(name);
}

快速检查

测试您对共享内存的理解。

回顾

您学会了共享内存,这是最快的 IPC。

  • 使用 shm_open、ftruncate,然后使用 MAP_SHARED 调用 mmap
  • 解引用指针来读写共享数据
  • 必须自行添加同步机制(信号量)
  • 使用 munmap、close 和 shm_unlink 清理资源

常见问题解答

「共享内存」课时是免费的吗?

是的 — 「共享内存」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C Academy 课程的其余内容,请升级到 CoddyKit PRO。 C Academy 课程共包含 4 节课。

「共享内存」这节课中我会学到什么?

快速 IPC 你通过在浏览器中直接运行的动手代码来练习 C Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「共享内存」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C Academy 课中编写并运行代码吗?

能。每节 C Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 管道
  2. 共享内存
  3. 消息队列
  4. 信号
← 返回 C Academy