Loading... # Linux中的System V通信标准——共享内存、消息队列以及信号量 在Linux系统中,System V IPC(Inter-Process Communication)提供了一系列进程间通信的机制,包括共享内存、消息队列和信号量。这些机制在系统中发挥了重要作用,帮助进程之间进行数据交换和同步。本文将详细介绍这些机制的概念、使用方法以及应用场景。 ![](https://www.8kiz.cn/usr/uploads/2024/07/306645620.png) ## 一、共享内存 ### 1.1 概念 共享内存(Shared Memory)是最快的一种进程间通信方式,它允许多个进程直接访问同一块内存区域,从而实现高效的数据交换。共享内存由内核管理,每个进程可以将共享内存段映射到自身的地址空间。 ### 1.2 使用方法 #### 创建和附加共享内存 创建或获取一个共享内存段: ```c #include <sys/ipc.h> #include <sys/shm.h> int shm_id = shmget(key_t key, size_t size, int shmflg); ``` 附加共享内存段到进程的地址空间: ```c void *shmaddr = shmat(int shm_id, const void *shmaddr, int shmflg); ``` #### 数据读写 共享内存的读写操作直接通过指针进行,如同普通内存操作。 #### 分离和删除共享内存 分离共享内存段: ```c int shmdt(const void *shmaddr); ``` 删除共享内存段: ```c int shmctl(int shm_id, IPC_RMID, NULL); ``` ### 1.3 示例代码 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> int main() { key_t key = ftok("shmfile", 65); int shm_id = shmget(key, 1024, 0666|IPC_CREAT); char *str = (char*) shmat(shm_id, (void*)0, 0); printf("写入数据到共享内存\n"); strcpy(str, "Hello, World!"); printf("数据: %s\n", str); shmdt(str); shmctl(shm_id, IPC_RMID, NULL); return 0; } ``` ## 二、消息队列 ### 2.1 概念 消息队列(Message Queue)是一种以消息为单位的进程间通信机制,允许一个或多个进程以有序的方式发送和接收消息。消息队列在内核中维护,进程通过消息队列标识符进行操作。 ### 2.2 使用方法 #### 创建和获取消息队列 创建或获取一个消息队列: ```c #include <sys/ipc.h> #include <sys/msg.h> int msg_id = msgget(key_t key, int msgflg); ``` #### 发送消息 ```c int msgsnd(int msg_id, const void *msgp, size_t msgsz, int msgflg); ``` #### 接收消息 ```c ssize_t msgrcv(int msg_id, void *msgp, size_t msgsz, long msgtyp, int msgflg); ``` #### 删除消息队列 ```c int msgctl(int msg_id, IPC_RMID, NULL); ``` ### 2.3 示例代码 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/msg.h> struct msg_buffer { long msg_type; char msg_text[100]; }; int main() { key_t key = ftok("msgfile", 65); int msg_id = msgget(key, 0666 | IPC_CREAT); struct msg_buffer message; message.msg_type = 1; strcpy(message.msg_text, "Hello, World!"); msgsnd(msg_id, &message, sizeof(message), 0); printf("消息发送: %s\n", message.msg_text); msgrcv(msg_id, &message, sizeof(message), 1, 0); printf("消息接收: %s\n", message.msg_text); msgctl(msg_id, IPC_RMID, NULL); return 0; } ``` ## 三、信号量 ### 3.1 概念 信号量(Semaphore)是一种用于同步进程操作的机制,可以控制多个进程对共享资源的访问。信号量可以是单个信号量(用于简单的互斥)或信号量集合(用于复杂的同步)。 ### 3.2 使用方法 #### 创建和获取信号量 创建或获取一个信号量集: ```c #include <sys/ipc.h> #include <sys/sem.h> int sem_id = semget(key_t key, int num_sems, int semflg); ``` #### 初始化信号量 ```c int semctl(int sem_id, int semnum, SETVAL, union semun arg); ``` #### 操作信号量 信号量操作包括P操作(等待)和V操作(信号),通常使用 `semop`函数进行操作。 ```c struct sembuf { unsigned short sem_num; short sem_op; short sem_flg; }; int semop(int sem_id, struct sembuf *sops, size_t nsops); ``` ### 3.3 示例代码 ```c #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/types.h> union semun { int val; struct semid_ds *buf; unsigned short *array; }; void sem_wait(int sem_id) { struct sembuf sem_op; sem_op.sem_num = 0; sem_op.sem_op = -1; sem_op.sem_flg = 0; semop(sem_id, &sem_op, 1); } void sem_signal(int sem_id) { struct sembuf sem_op; sem_op.sem_num = 0; sem_op.sem_op = 1; sem_op.sem_flg = 0; semop(sem_id, &sem_op, 1); } int main() { key_t key = ftok("semfile", 65); int sem_id = semget(key, 1, 0666 | IPC_CREAT); union semun sem_union; sem_union.val = 1; semctl(sem_id, 0, SETVAL, sem_union); if (fork() == 0) { sem_wait(sem_id); printf("子进程正在使用共享资源\n"); sleep(2); printf("子进程释放共享资源\n"); sem_signal(sem_id); } else { sem_wait(sem_id); printf("父进程正在使用共享资源\n"); sleep(2); printf("父进程释放共享资源\n"); sem_signal(sem_id); } semctl(sem_id, 0, IPC_RMID, sem_union); return 0; } ``` ## 四、总结 本文详细介绍了Linux中的System V通信标准,包括共享内存、消息队列和信号量。共享内存提供了最快的进程间通信方式,消息队列以消息为单位进行通信,信号量用于控制和同步进程对共享资源的访问。这些机制各有优劣,适用于不同的场景。在实际开发中,合理选择和使用这些机制,可以提高系统的性能和可靠性。 希望本文能帮助您更好地理解和应用System V IPC机制,构建高效的Linux应用程序。 最后修改:2024 年 07 月 30 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏