Linux中的System V通信标准--共享内存、消息队列以及信号量

简介: 希望本文能帮助您更好地理解和应用System V IPC机制,构建高效的Linux应用程序。

Linux中的System V通信标准——共享内存、消息队列以及信号量

在Linux系统中,System V IPC(Inter-Process Communication)提供了一系列进程间通信的机制,包括共享内存、消息队列和信号量。这些机制在系统中发挥了重要作用,帮助进程之间进行数据交换和同步。本文将详细介绍这些机制的概念、使用方法以及应用场景。

一、共享内存

1.1 概念

共享内存(Shared Memory)是最快的一种进程间通信方式,它允许多个进程直接访问同一块内存区域,从而实现高效的数据交换。共享内存由内核管理,每个进程可以将共享内存段映射到自身的地址空间。

1.2 使用方法

创建和附加共享内存

创建或获取一个共享内存段:

#include <sys/ipc.h>
#include <sys/shm.h>

int shm_id = shmget(key_t key, size_t size, int shmflg);
​

附加共享内存段到进程的地址空间:

void *shmaddr = shmat(int shm_id, const void *shmaddr, int shmflg);
​

数据读写

共享内存的读写操作直接通过指针进行,如同普通内存操作。

分离和删除共享内存

分离共享内存段:

int shmdt(const void *shmaddr);
​

删除共享内存段:

int shmctl(int shm_id, IPC_RMID, NULL);
​

1.3 示例代码

#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 使用方法

创建和获取消息队列

创建或获取一个消息队列:

#include <sys/ipc.h>
#include <sys/msg.h>

int msg_id = msgget(key_t key, int msgflg);
​

发送消息

int msgsnd(int msg_id, const void *msgp, size_t msgsz, int msgflg);
​

接收消息

ssize_t msgrcv(int msg_id, void *msgp, size_t msgsz, long msgtyp, int msgflg);
​

删除消息队列

int msgctl(int msg_id, IPC_RMID, NULL);
​

2.3 示例代码

#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 使用方法

创建和获取信号量

创建或获取一个信号量集:

#include <sys/ipc.h>
#include <sys/sem.h>

int sem_id = semget(key_t key, int num_sems, int semflg);
​

初始化信号量

int semctl(int sem_id, int semnum, SETVAL, union semun arg);
​

操作信号量

信号量操作包括P操作(等待)和V操作(信号),通常使用 semop函数进行操作。

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 示例代码

#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应用程序。

目录
相关文章
|
2月前
|
安全 Go 开发者
“不要通过共享内存来通信”——深入理解Golang并发模型与CSP理论
Golang 采用 CSP 理念,主张“通过通信共享内存”,以消息传递替代共享内存,避免数据竞争。其核心为 Goroutine 与 Channel:轻量协程并发执行,通道安全传递数据,将并发复杂性转为通信编排,提升程序清晰度与可维护性。
188 0
|
消息中间件 存储 监控
消息队列通信的优缺点
【10月更文挑战第29天】消息队列通信具有诸多优点,如解耦性强、异步通信、缓冲削峰等,能够有效地提高系统的灵活性、可扩展性和稳定性。但同时也存在一些缺点,如系统复杂性增加、性能开销、数据一致性挑战和实时性受限等。在实际应用中,需要根据具体的业务需求和场景,权衡其优缺点,合理地选择和使用消息队列通信机制,以实现系统的高效运行和优化。
|
消息中间件 存储 供应链
进程间通信方式-----消息队列通信
【10月更文挑战第29天】消息队列通信是一种强大而灵活的进程间通信机制,它通过异步通信、解耦和缓冲等特性,为分布式系统和多进程应用提供了高效的通信方式。在实际应用中,需要根据具体的需求和场景,合理地选择和使用消息队列,以充分发挥其优势,同时注意其可能带来的复杂性和性能开销等问题。
|
11月前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
807 20
|
12月前
|
Linux
【Linux】System V信号量详解以及semget()、semctl()和semop()函数讲解
System V信号量的概念及其在Linux中的使用,包括 `semget()`、`semctl()`和 `semop()`函数的具体使用方法。通过实际代码示例,演示了如何创建、初始化和使用信号量进行进程间同步。掌握这些知识,可以有效解决多进程编程中的同步问题,提高程序的可靠性和稳定性。
618 19
|
Linux
linux c 信号量编程
信号量 当我们在多用户系统,多进程系统,或是两者混合的系统中使用线程操作编写程序时,我们经常会发现我们有段临界代码,在此处我们需要保证一个进程(或是一个线程的执行)需要排他的访问一个资源。
948 0
|
3月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
二、Linux文本处理与文件操作核心命令
|
3月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
305 137
|
3月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
699 57
|
2月前
|
存储 安全 Linux
Linux卡在emergency mode怎么办?xfs_repair 命令轻松解决
Linux虚拟机遇紧急模式?别慌!多因磁盘挂载失败。本文教你通过日志定位问题,用`xfs_repair`等工具修复文件系统,三步快速恢复。掌握查日志、修磁盘、验重启,轻松应对紧急模式,保障系统稳定运行。
451 2

热门文章

最新文章