Linux进程间通信:实现协作与数据交换的多种方式

简介: 多任务并发执行是一种常见的应用场景。在Linux操作系统中,进程间通信(Inter-Process Communication,IPC)是实现多任务协作与数据交换的关键技术。本文将介绍Linux中常用的IPC方式,包括管道、消息队列、共享内存和套接字。

一、管道(Pipe):
管道是Linux中最简单的进程间通信机制,主要用于在具有亲缘关系的进程间传递数据。它是单向的,可以分为无名管道和有名管道。

代码示例:

#include <stdio.h>
#include <unistd.h>

int main() {
   
    int fd[2];
    char buf[256];
    pipe(fd);

    if (fork() == 0) {
    // 子进程
        close(fd[0]); // 关闭读端
        write(fd[1], "Hello from child!", 17);
    } else {
    // 父进程
        close(fd[1]); // 关闭写端
        read(fd[0], buf, sizeof(buf));
        printf("Parent received: %s\n", buf);
    }

    return 0;
}

二、消息队列(Message Queue):
消息队列是一种进程间通信方式,用于在无关联进程之间传递消息。消息队列是有名字的,允许进程通过消息队列进行异步通信。

代码示例:

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

struct msgbuf {
   
    long mtype;
    char mtext[256];
};

int main() {
   
    int msqid;
    struct msgbuf message;
    key_t key = ftok(".", 'm');
    msqid = msgget(key, IPC_CREAT | 0666);

    if (fork() == 0) {
    // 子进程
        message.mtype = 1;
        sprintf(message.mtext, "Hello from child!");
        msgsnd(msqid, &message, sizeof(message.mtext), 0);
    } else {
    // 父进程
        msgrcv(msqid, &message, sizeof(message.mtext), 1, 0);
        printf("Parent received: %s\n", message.mtext);
    }

    return 0;
}

三、共享内存(Shared Memory):
共享内存是一种高效的IPC方式,允许多个进程共享同一段物理内存。但需要注意同步访问共享内存的问题。

代码示例:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main() {
   
    int shmid;
    char *shmaddr;
    key_t key = ftok(".", 's');
    shmid = shmget(key, 256, IPC_CREAT | 0666);
    shmaddr = (char *)shmat(shmid, NULL, 0);

    if (fork() == 0) {
    // 子进程
        sprintf(shmaddr, "Hello from child!");
    } else {
    // 父进程
        wait(NULL); // 等待子进程写入数据
        printf("Parent received: %s\n", shmaddr);
    }

    return 0;
}

四、套接字(Socket):
套接字是一种通用的IPC方式,可以用于本地进程间通信,也可以用于不同主机之间的网络通信。

代码示例:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main() {
   
    int sockfd, newsockfd, portno;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    socklen_t clilen;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    portno = 12345;

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);
    bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    listen(sockfd, 5);

    if (fork() == 0) {
    // 子进程
        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
        write(newsockfd, "Hello from child!", 17);
    } else {
    // 父进程
        wait(NULL); // 等待子进程写入数据
        read(sockfd, buffer, sizeof(buffer));
        printf("Parent received: %s\n", buffer);
    }

    return 0;
}

结论:
Linux提供了多种进程间通信方式,每种方式都适用于不同的场景。管道适合父子进程之间简单数据传递,消息队列适用于无关联进程的异步通信,共享内存是高效的大数据交换方式,套接字提供通用的跨网络或本地进程间通信能力。

在实际应用中,开发者需要根据具体场景选择合适的IPC方式,并注意处理好进程间的同步与数据安全问题。正确选择IPC机制可以提高系统性能和开发效率,使进程间的通信更加稳定可靠。

目录
相关文章
|
7月前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
285 67
|
6月前
|
Web App开发 Linux 程序员
获取和理解Linux进程以及其PID的基础知识。
总的来说,理解Linux进程及其PID需要我们明白,进程就如同汽车,负责执行任务,而PID则是独特的车牌号,为我们提供了管理的便利。知道这个,我们就可以更好地理解和操作Linux系统,甚至通过对进程的有效管理,让系统运行得更加顺畅。
202 16
|
6月前
|
Unix Linux
对于Linux的进程概念以及进程状态的理解和解析
现在,我们已经了解了Linux进程的基础知识和进程状态的理解了。这就像我们理解了城市中行人的行走和行为模式!希望这个形象的例子能帮助我们更好地理解这个重要的概念,并在实际应用中发挥作用。
141 20
|
7月前
|
关系型数据库 MySQL Linux
在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾
以上就是在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾的步骤。这个过程就像是一场接力赛,数据从MySQL数据库中接力棒一样传递到备份文件,再从备份文件传递到其他服务器,最后再传递回MySQL数据库。这样,即使在灾难发生时,我们也可以快速恢复数据,保证业务的正常运行。
360 28
|
5月前
|
监控 Shell Linux
Linux进程控制(详细讲解)
进程等待是系统通过调用特定的接口(如waitwaitpid)来实现的。来进行对子进程状态检测与回收的功能。
125 0
|
5月前
|
存储 负载均衡 算法
Linux2.6内核进程调度队列
本篇文章是Linux进程系列中的最后一篇文章,本来是想放在上一篇文章的结尾的,但是想了想还是单独写一篇文章吧,虽然说这部分内容是比较难的,所有一般来说是简单的提及带过的,但是为了让大家对进程有更深的理解与认识,还是看了一些别人的文章,然后学习了学习,然后对此做了总结,尽可能详细的介绍明白。最后推荐一篇文章Linux的进程优先级 NI 和 PR - 简书。
186 0
|
5月前
|
存储 Linux Shell
Linux进程概念-详细版(二)
在Linux进程概念-详细版(一)中我们解释了什么是进程,以及进程的各种状态,已经对进程有了一定的认识,那么这篇文章将会继续补全上篇文章剩余没有说到的,进程优先级,环境变量,程序地址空间,进程地址空间,以及调度队列。
127 0
|
5月前
|
Linux 调度 C语言
Linux进程概念-详细版(一)
子进程与父进程代码共享,其子进程直接用父进程的代码,其自己本身无代码,所以子进程无法改动代码,平时所说的修改是修改的数据。为什么要创建子进程:为了让其父子进程执行不同的代码块。子进程的数据相对于父进程是会进行写时拷贝(COW)。
162 0
|
7月前
|
缓存 Linux
如何创建Linux交换文件?Linux交换文件最新创建方法
Swap是Linux中的虚拟内存空间,用于在物理内存不足时将非活动进程移至磁盘,从而优化活动进程的性能。通过创建交换文件(如1GB),可灵活调整交换空间而无需重新分区。步骤包括:使用`fallocate`或`dd`创建文件、设置权限 (`chmod 600`)、格式化 (`mkswap`)、启用交换 (`swapon`)、修改`/etc/fstab`以持久化配置,以及调整`vm.swappiness`值(默认60,建议从10开始)来平衡内存与交换的使用。最后通过`swapon -s`检查状态并重启生效。此方法适用于VPS和专用服务器,需以root用户操作。
222 2
|
8月前
|
存储 Linux 调度
【Linux】进程概念和进程状态
本文详细介绍了Linux系统中进程的核心概念与管理机制。从进程的定义出发,阐述了其作为操作系统资源管理的基本单位的重要性,并深入解析了task_struct结构体的内容及其在进程管理中的作用。同时,文章讲解了进程的基本操作(如获取PID、查看进程信息等)、父进程与子进程的关系(重点分析fork函数)、以及进程的三种主要状态(运行、阻塞、挂起)。此外,还探讨了Linux特有的进程状态表示和孤儿进程的处理方式。通过学习这些内容,读者可以更好地理解Linux进程的运行原理并优化系统性能。
329 4