IPC
当谈到IPC(Inter-Process Communication,进程间通信)时,它是指不同进程之间进行数据交换和通信的机制。
它允许在操作系统中运行的不同进程之间传输数据,这些进程可以是在同一台计算机上运行的不同应用程序,也
可以是在不同计算机上运行的不同应用程序。
IPC有多种实现方式,包括管道、消息队列、共享内存、信号量、套接字等。每种方式都有自己的特点和适用场景。
Linux 提供有SystemV 和 POSIX 两种接口:
SYSTEM V的接口使用时间比较久,应用广泛,很多旧的产品功能采用;
POSIX的接口设计较好,学习使用都比较容易。
个人觉得如果是新的代码还是采用POSIX接口比较好。
system V 的IPC (消息队列、信号量、共享内存)
https://man7.org/linux/man-pages/man7/sysvipc.7.html
POSIX IPC 的是各种IPC分开说明的
https://man7.org/linux/man-pages/man7/mq_overview.7.html 消息队列
https://man7.org/linux/man-pages/man7/sem_overview.7.html 信号量
https://man7.org/linux/man-pages/man7/shm_overview.7.html 共享内存
看以上的文档基本上就够了。
附上POSIX的标准
https://pubs.opengroup.org/onlinepubs/9699919799/文章来源:https://www.toymoban.com/news/detail-678631.html
示例
共享内存
通过以下示例,可以了解一下POSIX与SystemV 的接口区别。文章来源地址https://www.toymoban.com/news/detail-678631.html
POSIX shm
// 一个主进程,负责往共享内存中写数据
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc, char **argv)
{
int ret;
int fd;
char *m;
int *t;
fd = shm_open("/somename", O_CREAT | O_RDWR, DEFFILEMODE); /* 这里有特别注意mode的取值,如果是0 的话,则可能导致其他进程无权限获取共享内存 */
if (fd < 0) {
printf("shm open fail. %s\n", strerror(errno));
return -1;
}
if (ftruncate(fd, 4) < 0) {
printf("ftruncate fail.\n");
goto error;
}
m = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (m == MAP_FAILED) {
printf("mmap error");
goto error;
}
t = (int *)m;
*t = 0;
while (1) {
(*t)++;
sleep(1);
}
munmap(m, 4);
error:
close(fd);
shm_unlink("/somename");
return 0;
}
// 另一个进程,读取共享内存的数据
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int ret;
int fd;
char *m;
int *t;
fd = shm_open("/somename", O_RDWR, 0);
if (fd < 0) {
printf("shm open fail.\n");
return -1;
}
m = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (m == MAP_FAILED) {
printf("mmap error");
goto error;
}
t = (int *)m;
while (1) {
printf("read %d\n", *t);
sleep(2);
}
munmap(m, 4);
error:
close(fd);
shm_unlink("/somename");
return 0;
}
System V shm
// 进程1 写入共享内存数据
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char **argv)
{
int shmid;
key_t key = 0x1234;
char *addr;
int *val;
shmid = shmget(key, 4, IPC_CREAT | DEFFILEMODE);
if (shmid < 0) {
printf("shmget fail\n");
return -1;
}
printf("get id %d\n", shmid);
addr = shmat(shmid, NULL, 0);
if (addr == (void *)-1) {
printf("shmat fail. %s\n", strerror(errno));
goto error;
}
val = (int *)addr;
*val = 0;
while (1) {
(*val)++;
sleep(1);
}
error:
shmctl(shmid, IPC_RMID, NULL);
return -1;
}
// 读取共享内存数据
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char **argv)
{
int shmid;
key_t key = 0x1234; /* 还可以用ftok 来生成一个与文件有关的key值,这里写死简化逻辑 */
char *addr;
int *val;
shmid = shmget(key, 4, 0);
if (shmid < 0) {
printf("shmget fail\n");
return -1;
}
printf("read id %d\n", shmid);
addr = shmat(shmid, NULL, 0);
if (addr == (void *)-1) {
printf("shmat fail.\n");
goto error;
}
val = (int *)addr;
while (1) {
printf("read %d\n", *val);
sleep(2);
}
error:
shmctl(shmid, IPC_RMID, NULL);
return -1;
}
到了这里,关于IPC之System V vs POSIX的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!