Linux相关概念和易错知识点(26)(命名管道、共享内存)

八.linux的进程间通信之管道、消息队列、共享内存简介 http://note.youdao.com/noteshare?id=e776f7ddbdee26e3d3a3f102b27174be&sub=725B6C7D7A074448AE46FDEF0B8682D5 目录 一、linux的进程间通信简介 1、进程间通信简介 2、多进程编程的优缺点 1、优点 2、缺点 二、linux的IPC机制1-管道 1、管道(无名管道) 2... 阅读详情

目录

1.命名管道

(1)匿名管道 -> 命名管道

①匿名管道

②命名管道

(2)命名管道的使用

①创建和删除命名管道文件

②命名管道文件的特性

③命名管道和匿名管道的区别

(3)用命名管道实现进程间通信

2.共享内存

(1)共享内存是什么

(2)shmget

①IPC_CREAT

②IPC_EXCL

③key

④shmid

(3)共享内存的生命周期及其释放

①指令释放

②代码释放

(4)shm的关联和去关联

①关联

②去关联

(5)shm申请空间的底层细节

(6)共享内存通信的特点

①优点

②缺点

(7)共享内存的保护

①临界与非临界、互斥同步

②信号量

(8)共享内存的底层


1.命名管道

(1)匿名管道 -> 命名管道

①匿名管道

匿名管道的原理是创建一个内存级文件pipe,让父子进程看到同一块文件缓冲区,利用同缓冲区、不同struct file的特性实现一个进程向缓冲区写入,一个向缓冲区读取。但这有个问题,匿名管道的创建前提就是通信的进程属于父子关系,但有的时候我们需要让不相关的进程进行通信,这应该怎么办呢?这就要引入命名管道了。

②命名管道

进程间通信的根本就是让两个进程看到同一块资源,因此我们需要找到一个让两个不相关的进程能够同时访问的资源。对于命名管道而言,这个公共资源就是一个真实的文件,以路径 + 文件名作为该文件的唯一标识。

(2)命名管道的使用

①创建和删除命名管道文件

创建命名管道文件:int mkfifo(const char *pathname, mode_t mode);

删除命名管道文件:int unlink(const char *pathname)

返回值:成功创建(删除)文件时返回0,失败返回-1并设置错误码

我们可以看到,命名管道文件是一个真实存在的文件,我们可以创建命名管道,通过对这个文件进行读写操作。具体方法就是通过路径 + 文件名操作。

需要注意的一个小细节就是创建、删除文件可以携带路径,通信的两个进程可以在任意位置,通过绝对/相对路径进行定位。

②命名管道文件的特性

为什么要专门设计这种文件?

其一是命名管道文件始终不会刷新写入内容到磁盘,都是写入内核缓冲区,等待读走。因此从效率上将要更快;

其二,就是命名管道文件存在一个特殊处理。即当创建好命名管道文件之后,会有读端和写端打开以进行通信。对于普通文件,读端写端可以直接打开已存在的文件;而对于命名管道文件而言,当一端打开而另一端还没有打开时,先打开的那一端就会被open阻塞,直到另一端打开,两者才会同时打开文件,之后read就会被阻塞(同步互斥保护机制)。这样做的目的是,当读端打开文件后会开始读文件,而如果此时没有写端打开,read会返回0,这就导致读端直接判断为“数据读完了”导致执行剩余代码,反之亦然。

因此普通文件虽然也能实现进程间通信,但会存在效率问题以及读写端时机导致的问题。显然我们离不开专门设计的命名管道文件。

③命名管道和匿名管道的区别

很明显,匿名、命名管道均利用文件内核缓冲区进行数据通信,但是匿名管道是因为父子进程才使得不同进程看到同一份资源,而命名管道是通过路径定位看到同一文件资源,所以进程A和进程B不需要为父子关系。除此之外,两种通信方式的原理一模一样,只有处理细节上的不同。

(3)用命名管道实现进程间通信

由于和匿名管道代码类似,这里我简要分析思路 + 代码展示即可。我们需要做的是先生成管道文件,这部分交给读端(服务端)处理,一般都是服务端等待客户端的接入,后续管道文件的销毁也是服务端处理。

common.hpp

#pragma once

#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

using namespace std;

const string filename = "./myfifo";
const int count = 50;//允许通信消息数

class myPipe
{
public:
    myPipe()
    {
        umask(0);
        int create_ret = mkfifo(filename.c_str(), 0600);
        if (create_ret == 0)
            cout << "创建命名管道文件成功!" << endl;
        else
        {
            cout << "创建命名管道文件失败!" << endl;
            exit(1);
        }
    }

    ~myPipe()
    {
        int unlink_ret = unlink(filename.c_str());
        if (unlink_ret == 0)
            cout << "删除命名管道文件成功!" << endl;
        else
        {
            cout << "删除命名管道文件失败!" << endl;
            exit(1);
        }
    }

};

client.hpp



#include "common.hpp"

class Client
{
public:
    Client()
        : _fd(-1)
    {
        _fd = open(filename.c_str(), O_WRONLY);

        if (_fd > 0)
            cout << "客户端通信已连接!" << endl;
        else
        {
            cout << "客户端通信连接失败!" << endl;
            exit(1);
        }
    }

    int WriteMessage()
    {
        string str;
        getline(cin, str);
        write(_fd, str.c_str(), str.size());
        return str.size();//内核缓冲区中字符串结尾不需要\0
    }

    ~Client()
    {
        if (close(_fd) == 0)
            cout << "通信结束,客户端已断开!" << endl;
        else
            cout << "通信结束,但客户端断开失败!" << endl;
    }

private:
    int _fd;
};

server.hpp



#include "common.hpp"


myPipe mypipe;


class Server
{
public:
    Server()
        : _fd(-1)
    {
        _fd = open(filename.c_str(), O_RDONLY);

        if (_fd > 0)
            cout << "服务端通信已连接!" << endl;
        else
        {
            cout << "服务端通信连接失败!" << endl;
            exit(1);
        }
    }

    int ReadMessage(string& str)
    {
        char arr[100] = { 0 };
        read(_fd, arr, 99);
        str = arr;

        return str.size();//内核缓冲区中字符串结尾不需要\0
    }

    ~Server()
    {
        if (close(_fd) == 0)
            cout << "通信结束,服务端已断开!" << endl;
        else
            cout << "通信结束,但服务端断开失败!" << endl;
    }

private:
    int _fd;
};

client.cc


#include "client.hpp"

int main()
{
    Client client;

    int client_count = count;

    while (client_count--)
    {
        printf("客户端输入(剩余通信消息数%d):", client_count + 1);
        if(client.WriteMessage() == 0)
	    client_count++;
    }

    return 0;
}

server.cc


#include "server.hpp"

int main()
{
    Server server;

    while (1)
    {
        string str;
        server.ReadMessage(str);
        if(str.size() == 0)
        {
            cout << "客户端已退出且消息已全部接收" << endl;
            break;
        }
        printf("服务端接收信息:");
        cout << str << endl;
    }

    return 0;
}

2.共享内存

(1)共享内存是什么

进程地址空间的共享区除了映射共享库,还可以映射内存空间,这些空间叫共享内存。其原理就是利用共享区偏移量定位的特性让同一块物理空间映射到多个进程的地址空间的共享区,让它们看到同一块空间。

管道通信(文件内核缓冲区)基于文件,共享内存(共享区)属于system V标准。

抓住进程通信本质——让不同进程看到同一份资源。对于system V标准来说,通信的流程为:某个进程创建共享内存,并将它挂接到其它进程的进程地址空间中(堆栈之间)。

和共享内存关联和去关联的过程就是与页表映射和清除映射的过程。共享内存可以存在很多个,需要管理。共享内存 = 共享内存的内核数据结构 + 内存块。通常是由使用的进程来创建共享内存的。

(2)shmget

函数参数:int shmget(key_t key, size_t size, int shmflg),其中size是开辟空间大小

shmflg是宏定义选项,有IPC_CREAT和IPC_EXCL

①IPC_CREAT

创建内存,单独使用时,表示如果shm不存在,就创建,如果已经存在,就直接获取并返回,保证调用进程能拿到共享内存,无论是新建还是已经有了的

②IPC_EXCL

单独使用无意义,需要和IPC_CREAT联合使用。如果shm存在就出错返回,主要用于新建共享内存,函数只要成功,就一定是新的共享内存,不会使用已经创建的共享内存

③key

共享内存可以有多个,怎么确定是哪一个共享内存?因此共享内存要有唯一的标识符key。创建共享内存的key必须是用户输入的,因为它是函数参数之一。

但是这个key为什么要用户自己输入,不能系统内核自己生成吗?假设这个key是系统自己生成的,那么当shm的key交给进程A之后,进程B怎么拿到key(进程A和B独立)?因为进程B和shm没有任何关系,和进程A也没关系,所以内核层面无法将shm挂接到进程B上。我们需要用户介入,让用户一开始就自定义key,这样当创建shm后,进程A和B都知道这个key是多少(采用公共的头文件即可实现该操作)。

总的来说,key由用户层去设置更容易管理,但key怎么设置呢?理论上只要不冲突,就可以随便设。如果冲突,就会出错,需要手动改,如果我们不希望自己去设置,可以使用key_t ftok(const char *pathname, int proj_id);,这个函数会根据函数参数自动生成一个唯一值,尽量减少冲突。其中pathname最好填和文件名相关的路径,proj_id也是自己指定,公共的项目ID。函数参数并没有强制要求,只是生成唯一数的一个函数,我们尽量按照其设计来填。ftok成功就返回key,失败返回-1。

我们可以说key的唯一性是由项目ID + 路径实现的,和命名管道(文件路径)有异曲同工之妙,这也是系统的树状存储结构带来的优势。

④shmid

shmid是shmget函数的返回值。shmid不是key,但shmid和key都具有唯一性,两者的区别是key是内核使用的,shmid是只给用户使用的标志shm的标识符。我们只在创建时自定义一次key,后续都使用shmid来管理shm。

这里很难理解,为什么要设置一个shmid,不是我们已经知道key了吗?

我们可以理解为shmid是一个底层的标志,我们用户第一次设置了之后就被系统拿去做唯一标识符了。从安全性、可维护性角度出发,系统直接掌握的东西是不会直接交给用户使用的。就好比物理内存地址和虚拟地址一样,我们设置虚拟地址就是为了让数据存储更易管理,有个中间层要方便、安全得多。再如fd和struct file,我们本来知道struct file的地址即可,却还要设置一个fd作为用户层的管理,也都是有安全性、可维护性的原因的。shmid就是这么诞生的。虽然由于规则的特殊性,我们用户一来就知道了key的值,但由于这个值会直接用于系统的使用,因此还是要一个中间层来进行管理,即shmid。我们直接将shmid理解为fd,key理解为struct file对应的地址即可。

shmid的出现是有理有据的,只不过由于特殊需求,用户知道了key的值,但系统的底层逻辑不允许人们直接拿着这个key去管理内存,这里需要我们花时间理解。

(3)共享内存的生命周期及其释放

共享内存属于系统侧的内存空间,其生命周期随内核,因此它需要手动释放或是OS重启才会回收。相比之下匿名管道随进程,命名管道也要保证随进程的生命周期。

释放共享内存的方式有指令释放、代码释放。

①指令释放

ipcrm -m (shmid)可以释放共享内存,注意这个shmid在进程结束后依然存在,且一直保持唯一。

在命令行中,共享内存的管理指令为ipcs -m,它可查看系统中的共享内存的各种属性(包括shmid)

ipcs -m查看的perms相当于权限,共享内存也有权限,shmget函数的shmflg可以 | mode设置共享内存的读写权限,如int shmget(key_t key, size_t size, int shmflg | 0666)会使得三个组都获得所有权限。perms可以设置一次,如果没有权限,相应进程无法挂接内存,挂接成功后nattch会++,表示引用计数。

②代码释放

参数:int shmctl(int shmid, int cmd, shmid_ds* buf)

shmid_ds类型含有shm的各种属性,cmd是通过位图标识各种命令操作。ipcs -m的底层实现就是使用这个函数。

不同的cmd对应不同操作,IPC_STAT就是拷贝属性到buf,可以以此实现ipcs -m命令,查看对应内存的属性;IPC_RMID就是让对应内存空间标记释放,shmid_ds* buf传nullptr,表示不获取相应的属性。例如shmctl(0, IPC_RMID, nullptr)可以利用代码释放共享内存,这就是ipcrm -m 0的底层代码实现。

(4)shm的关联和去关联

①关联

要使用shm,需要将其挂接到进程地址空间的共享区。

函数参数:void *shmat(int shmid, const void *_Nullable shmaddr, int shmflg);

shmaddr是用户指定挂接到什么虚拟地址,对我们来说直接设置为nullptr即可,表示不指定具体挂接位置。shmflg也是位图,表示访问权限,这里我们可以直接设置为0。shmat的返回值是虚拟起始地址,由返回值 + 偏移量我们即可完全访问这块空间,这和malloc类似,shmat挂接错误的话返回(void*)-1。

我们发现挂接后得到的返回值就相当于malloc的返回值,我们可以强转指针类型为不同类型,对这片空间进行不同方式的访问,如此这样这块公共空间就利用起来了。

②去关联

函数参数:int shmdt(const void *shmaddr);

只要知道共享内存的虚拟起始地址,就能取消映射,对应的内存空间引用计数nattch--。

通信的过程就在shmat和shmdt函数的调用之间。使用和malloc一模一样。

(5)shm申请空间的底层细节

使用shmget申请空间的过程中,操作系统是按照页为单位申请的:1KB、2KB、4MB等。操作系统会根据用户的需要来给内存,但其底层可能会浪费。

(6)共享内存通信的特点

①优点

当挂接好之后,我们拿着共享内存的虚拟地址就能直接往内存读写数据,因此共享内存速度最快。另外,从拷贝角度上讲,共享内存拷贝的次数最少,当拷贝数据到共享内存时,两个进程就能马上看到数据。

②缺点

两个进程在各自用户空间共享内存块,和malloc一样可以自由使用。但由于这块共享内存没有加任何保护机制,需要用户自己完成共享内存的保护——信号量、命名管道等。

(7)共享内存的保护

①临界与非临界、互斥同步

共享资源大多都要被保护,这些叫临界资源。常见保护方式有互斥、同步。任何时刻只允许进行一个执行流访问的资源,叫做互斥,即系统中某些资源一次只允许一个人使用。同步是指多个执行流访问临界资源时必须要有一定的顺序。

在进程中代码涉及到临界资源,这部分代码就叫临界区。代码 = 临界区的代码 + 非临界区的代码,临界区访问临界资源,非临界区访问非临界资源。对共享资源进行保护的本质是对访问共享资源的代码进行保护,就是保护临界区的代码。

②信号量

信号和信号量没有任何关系。

信号量的特性是IPC(系统资源),必须手动删除。信号量本质是一个计数器,这个计数器可以是一个位图、数字。我们将资源分成不同块,不同进程都使用同一块空间的不同部分,针对每一个小块,保证互斥访问,但当一个数据块读时,另一个在写,整体上看并行度提高。

从一个例子出发,当我们买了电影票,即便我们不去,这个位置也是留给我们的。并且从不会多卖出去票,10个座位不会卖出11张票。我们可以理解,买票的本质是对资源的预定机制,进程也是!

信号量就是一个计数器,这个计数器也是资源的预定。多个进程划分资源都是抢计数器而不是直接去抢空间。信号量、信号灯都是对资源进行预定的计数器。二元信号量,1表示被使用,0没被使用。要实现信号量,我们可以用位图标识每块资源的使用情况,也可以直接用数字count统计剩余资源的个数,总之需要保证内部划分合理且不会出现冲突。

(8)共享内存的底层

共享内存本质也是文件,这个文件必须被映射到进程地址空间。共享内存文件创建后,vm_area_struct会进行映射,把文件映射到内存中了。和动态库一样是内存都是被映射到文件中的。

进程间通信---对管道的详细讲解(图文案例讲解) 1. 管道 1.1什么是管道 2. 匿名管道 2.1 用fork来共享管道原理 2.2 站在文件描述符角度-深度理解管道 2.3站在内核角度-管道本质 2.4 管道特点 3.管道读写规则 4. 命名管道 阅读详情

相关推荐

Linux之进程间通信(一)---管道

进程是一个独立的资源分配单位,每个进程的资源都是独立的,有独立的用户地址空间,当有多个进程同时存在时,当有一个进程突然出现异常时,其它的进程是不受影响的.那么,有时候就需要不同进程的信息进行交换或传递才可以工作.所以就出现了进程间通信. 进程间通信的目的: 数据传输:一个进程需要将它的数据发送给另一个进程. 资源共享:多个进程之间共享同样的资源(比如:共享同一段内存). 通知事件:一个进...

Yinghuhu333333的博客 480

【Linux学习】进程间通信的方式(匿名管道、命名管道、共享内存)

进程间通信(IPC,Interprocess communication)是一组编程接口,让程序员能够协调不同的进程,使之**能在一个操作系统里同时运行,并相互传递、交换信息。

qq_61635026的博客 1295

摄像头visio_最全面弱电智能VISIO图标集(百个),高大上方案就靠这个了

原标题:最全面弱电智能VISIO图标集(百个),高大上方案就靠这个了不会用Visio,Visio画拓扑画的很丑,怎么办?本期sin66小编免费分享一份最全面的弱电智能VISIO图标集(百个)给大家,以后画拓扑、做方案,直接高大上起来!需要本期资料直接看文末!!接下来我们一起看一下这些Visio图标大全:我们从下图可以看出前端设备主要是由枪机,筒机,无线摄像头,半球,球机,USB摄像头等构成,对于绘...

weixin_39644915的博客 1万+

Linux进程通信 ---匿名/命名管道 --- 共享内存

进程通信,匿名管道,命名管道,共享内存

CHJBL的博客 627

VisDrone2019数据集实战:从下载到YOLO格式转换的完整指南

本文提供了一份完整的VisDrone2019数据集实战指南,详细介绍了从数据集下载、理解其独特的标注格式,到转换为YOLO模型可直接训练格式的全过程。通过清晰的代码示例和步骤讲解,帮助读者掌握处理复杂无人机视觉数据集的核心技能,为基于YOLO的目标检测模型训练做好准备。

weixin_29165725的博客 384

CANoe的安装教程

CANoe的安装教程

weixin_59090531的博客 1万+

【Linux】命名管道 && 共享内存

世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!提示:以下是本篇文章正文内容,下面案例可供参考好了,本篇博客到这里就结束了,如果有更好的观点,请及时留言,我会认真观看并学习。不积硅步,无以至千里;不积小流,无以成江海。

2301_79585944的博客 1490

Miniconda3迁移(附图详细过程)

服务器上目录占满,想要将conda迁移到其他目录下的操作方法,详细教程。

2301_77554343的博客 6942

Linux进程通信:命名管道,System V共享内存

Linux进程通信:命名管道,System V共享内存

xiao_xiao21的博客 1025

自定义配方画面的具体方法示例 - 嵌入式

自定义配方画面的具体方法示例 - 嵌入式在TIA博途WinCC中,您可以通过编程来创建自定义配方画面。这些画面可以用于显示和编辑您的嵌入式系统中的配方参数。下面是一个示例,展示了如何在WinCC中实现自定义配方画面的方法。首先,您需要创建一个新的画面,并添加必要的控件来显示和编辑配方参数。在WinCC中,您可以使用文本框、按钮和标签等控件来实现这一目的。以下是一个简单的示例,展示了如何创建一个具有文本框和按钮的配方画面:创建新画面:添加控件:编辑控件属性:编写脚本: 在这个示例中,我们定义了两个变量和来存储

CyberBytezZ的博客 1034

【DRAM存储器六十二】DDR5介绍--引脚和基本功能简介

详述DDR5与DDR4的引脚区别和DDR5基本功能

highman110的博客 523

【Linux】进程间通信——命名管道和共享内存

我们不得不说,共享内存是最快的进程间通信的方式,因为一个进程只需要把数据写入到它的地址空间中(其实就是写到了物理内存中),另一个进程就可以看到,这是它的优点,但是共享内存是不提供进程间协同的机制的,就是你写你的我读我的,这就会导致你可能还没写完我就读了,这就导致信息丢失。这个函数有两个参数,其实我们可以随便给一个路径,一个proj_id,只要它们是唯一的即可,这样就可以生成唯一的key值,不同的进程间只要传入相同的路径和proj_id,它们就能获得相同的key值,找到同一块共享内存。

2201_76024104的博客 1351

组建高效AI开发团队:角色、技能与协作

在当今科技飞速发展的时代,人工智能(AI)已经成为各个领域的核心驱动力。组建高效的AI开发团队对于企业和科研机构来说至关重要,它能够推动创新、提高竞争力、实现业务目标。本文的目的在于为那些希望组建或优化AI开发团队的管理者、技术负责人以及相关从业者提供全面的指导。范围涵盖了团队角色的定义、所需技能的分析、团队协作的策略,以及实际项目中的应用和相关资源的推荐。本文将首先介绍AI开发团队的核心概念与联系,包括团队角色、技能和协作之间的关系。接着阐述核心算法原理和具体操作步骤,结合数学模型和公式进行详细讲解。

2502_91592937的博客 995

【Linux进程间通信】深入探索:Linux下的命名管道与System V共享内存

@TOC????前言:在Linux操作系统中,进程间通信(IPC)是一个至关重要的概念,它允许不同的进程之间进行数据交换和同步。随着现代操作系统的日益复杂,进程间通信的重要性也日益凸显。在众多IPC机制中,命名管道和System V共享内存无疑是两种最为常见且强大的工具命名管道,又称为FIFO(First In First Ou...

Java_fenxiang的博客 862

【tio-websocket】15、学习tio的第1步—tio-study

tio-study 是用于学习 t-io 的示范工程,tio-study 是入门 t-io 最好的方式!tio-study 工程演示的是一个典型的 TCP 长连接应用工程,分为 server(服务端) 和 client(客户端) 工程,server 和 client 共用 common(公共模块) 工程

JACKAL 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

linux:命名管道与共享内存

本文介绍了Linux中的两种进程间通信机制:命名管道和System V IPC。命名管道通过特殊管道文件实现无血缘关系进程的通信,需使用mkfifo创建并遵循"打开-读写-关闭"操作流程。System V IPC重点讲解了共享内存(shm),其特点是通信速度最快但需自行处理同步问题,涉及shmget创建、shmat挂接、shmdt分离和shmctl控制等系统调用。此外还简要提及消息队列(msg)和信号量(sem),信号量主要用于进程同步互斥,通过PV操作实现原子性资源管理。所有Syste

qq_72916130的博客 420

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Linux 进程间通信:匿名管道、命名管道、共享内存、消息队列与信号量完全指南

本文总结Linux进程间通信(IPC)的5种主要方式:匿名管道、命名管道、共享内存、消息队列和信号量。重点讲解了匿名管道的原理与使用,包括pipe函数创建管道、fork共享管道、管道读写规则与特性。文章还通过代码示例展示了父子进程通过管道通信的实现方式,并分析了管道在内核中的本质是内存缓冲区+文件描述符。最后介绍了如何用管道构建进程池的进阶应用场景。全文以"Linux一切皆文件"思想贯穿,帮助读者从会用管道到理解其底层原理。

2601_95483298的博客 503

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

linux系统编程之管道(三):命名管道FIFO和mkfifo函数

进程间通信必须通过内核提供的通道,而且必须有一种办法在进程中标识内核提供的某个通道,前面讲过的匿名管道是用打开的文件描述符来标识的。如果要互相通信的几个进程没有从公共祖先那里继承文件描述符,它们怎么通信呢?内核提供一条通道不成问题,问题是如何标识这条通道才能使各进程都可以访问它?文件系统中的路径名是全局的,各进程都可以访问,因此可以用文件系统中的路径名来标识一个IPC通道。 FIFO

Meditation 3万+

【Linux系统编程】管道

Linux系统编程 管道

lyh030105的博客 1240

Linux学习笔记-----进程间通信(管道及共享内存)

要让两个不同进程通信,前提条件是让两个进程看到同一资源。 对于进程间要相互通信,我们引入管道和共享内存概念 管道是Unix中最古老的进程间通信的形式,要让两个不同进程通信,前提条件是让两个进程看到同一资源。管道的生命周期是随进程的。 共享内存是进程通信中最快的,ipc的生命周期随内核,共享内存底层不提供任何的互斥机制。 一、匿名管道 匿名管道用于进程之间通信,且仅限于本地父子进程之间通信(兄弟、爷孙之间都可以,只要有亲缘关系),结构简单,类似于一根非水平状态的水管,一端进水另一端出水(单工)。相对于命.

qq_41219243的博客 430

Linux进程间通信(IPC)、管道、消息队列、共享内存、信号量、信号

Linux进程间通信(IPC)管道、消息队列、共享内存、信号、信号量一、管道1.1 无名管道1.2 命名管道(FIFO)二、消息队列三、共享内存四、信号量五、信号信号的名字和编号信号处理函数的注册和发送管道举例消息队列举例共享内存举例信号量举例信号举例 管道、消息队列、共享内存、信号、信号量 一、管道 定义:管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。 1.1 无名管道 特点: 半双工。(同一时间,数据单向流通) 只应用在父子或者兄弟进程之间。 数据读取后,管道中的数据即不存在了。 #m

Jackice_Lee的博客 1121

Linux进程间通信—无名管道和命名管道

无名管道(pipe)管道是linux进程间通信的一种方式,如命令ps -ef | grep ntp 无名管道的特点: 1、只能在亲缘关系进程间通信(父子或兄弟) 2、半双工(固定的读端和固定的写端) 3、是特殊的文件,可以用read、write等,只能在内存中管道函数原型: #include <unistd.h> int pipe(int fds[2]);函数pipe用于创建一个无

未来之歌 1454

Linux进程间通信(管道,FIFO,消息队列,信号量,共享内存)

进程间通信:简称ipc(Inter-Process Communication)。进程间通信是指两个进程的数据之间产生交互。 一.无名管道(pipe) 1.特点: ①半双工(即数据只能在一个方向上流动),具有固定的写端和读端 ②只能用于父子进程或兄弟进程之间 ③可以把它当做是一个文件使用read等函数操作,但它不是普通文件,并不属于其他文件系统,只存于内存中。 2.原型: 1. #include <unistd.h> 2. Int pipe(int fd[2]); //返回值,

weixin_58670878的博客 550

Linux进程间通信—管道

前言:本篇主要总结介绍了Linux进程间通信方式之一管道技术。包括管道(无名有名)的基本概念、相关API的介绍、及Demo代码示例。

Caso_卡索的博客 509

Linux进程间通信

概念 进程间通信本质让不同的进程,看到同一份资源内存,文件内核缓冲等) 资源由谁(os中的那些模块)提供,就有了不同的进程 如何实现进程间通信 1.进程之间是具有独立性的,所以难以直接通信 2…进程间通信,一般一定要借助第三方(OS)资源 3.通信的本质就是”数据的拷贝“ 进程A->数据"拷贝"给OS的一段内存区域->OS数据"拷贝"给进程B 这样通过OS这个“媒介”就实现了进程A与进程B的通信 进程通信的目的 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资

hbbfvv1h的博客 2791
上一篇: Linux相关概念和易错知识点(25)(信号原理、操作系统的原理、volatile)
下一篇: Linux相关概念和易错知识点(27)(认识线程、页表与进程地址空间、线程资源划分)
-SGlow-
博客等级 码龄3年 1513粉丝 118原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值