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机制可以提高系统性能和开发效率,使进程间的通信更加稳定可靠。

目录
相关文章
|
1天前
|
存储 Linux 程序员
【Linux-14】进程地址空间&虚拟空间&页表——原理&知识点详解
【Linux-14】进程地址空间&虚拟空间&页表——原理&知识点详解
|
1天前
|
Unix Linux
【Linux】一文了解【进程优先级相关知识点】&【PRI / NI值】背后的修正原理(13)
【Linux】一文了解【进程优先级相关知识点】&【PRI / NI值】背后的修正原理(13)
|
1天前
|
Linux 调度
【Linux】盘点广义层面上【三种最基本的进程状态】
【Linux】盘点广义层面上【三种最基本的进程状态】
|
1天前
|
Linux Shell
【Linux】深度解析Linux中的几种进程状态
【Linux】深度解析Linux中的几种进程状态
|
1天前
|
Linux Shell 调度
【Linux】用三种广义进程状态 来理解Linux的进程状态(12)
【Linux】用三种广义进程状态 来理解Linux的进程状态(12)
|
1天前
|
Linux Shell 调度
【Linux系列】fork( )函数原理与应用详解——了解【父子进程及其特性】(代码演示,画图帮助理解,思维导图,精简)(11)
【Linux系列】fork( )函数原理与应用详解——了解【父子进程及其特性】(代码演示,画图帮助理解,思维导图,精简)(11)
|
1天前
|
Linux Shell
【Linux】解决:为什么重复创建同一个【进程pid会变化,而ppid父进程id不变?】
【Linux】解决:为什么重复创建同一个【进程pid会变化,而ppid父进程id不变?】
|
2天前
|
算法 大数据 Linux
深入理解Linux内核的进程调度机制
【4月更文挑战第30天】操作系统的核心职能之一是有效地管理和调度进程,确保系统资源的合理分配和高效利用。在众多操作系统中,Linux因其开源和高度可定制的特点,在进程调度机制上展现出独特优势。本文将深入探讨Linux内核中的进程调度器——完全公平调度器(CFS),分析其设计理念、实现原理及面临的挑战,并探索未来可能的改进方向。
|
2天前
|
存储 Web App开发 运维
|
2天前
|
Linux

热门文章

最新文章