精华内容
下载资源
问答
  • 实验六Linux 进程间通信2 4 课时 实验目的 理解进程通信原理掌握进程中信号量共享内存消息队列相关的函数的使用 实验原理 Linux 下进程通信相关函数除上次实验所用的几个还有 信号量 信号量又称为信号灯它是用来协调...
  • 本文件源自网络,经过了本人自己的验证与修订。所有例程都经过了测试。
  • 实验六Linux进程间通信24课时 实验目的 理解进程通信原理掌握进程中信号量共享内存消息队列相关的函数的使用 实验原理 Linux下进程通信相关函数除上次实验所用的几个还有 信号量 信号量又称为信号灯它是用来协调不同...
  • 从国外的一个网站上看到的,感觉写的不错,可以参考看看
  • 主要介绍了浅谈Linux进程间通信方式及优缺点,具有一定参考价值,需要的朋友可以了解下。
  • 主要介绍了Linux进程间通信方式之socket使用实例,具有一定参考价值,需要的朋友可以了解下。
  • linux进程间通信

    2018-07-27 11:44:40
    linux 多进程, 进程间通信。 开发实例。
  • Linux 进程间通信

    2012-12-16 23:24:10
    Linux进程间通信实现方式,比如管道、消息队列等
  • 消息队列和过程调用往往单独使用,也就是说它们通常提供了自己的同步机制.相反,共享内存区通常需要由应用程序提供的某种同步形式才能正常工作.解决某个特定问题应使用哪种IPC不存在简单的判定,应该逐渐熟悉各种IPC...
  • 详细讲解了管道、信号、 消息队列、 信号灯 、共享内存、 套接口。
  • linux 进程间通信及多线程操作源码

    热门讨论 2012-02-27 13:42:29
    全双工邮箱通讯,两个程序分别同过共享内存(邮箱)相互传输数据, 分别都有一个读写线程,读写个自通讯数据区域,一个读线程对应另一个进程的写线程;
  • 一个大型的应用系统,往往需要众多...本系列文章阐述了Linux环境下的几种主要进程间通信手段,并针对每个通信手段关键技术环节给出详细实例。为达到阐明问题的目的,本文还对某些通信手段的内部实现机制进行了分析。
  • Linux系统中的进程间通信是典型的虚拟内存系统中的进程间通信Linux进程间通信是不同进程间交换数据的机制。由于Linux系统支持虚拟内 存, 对于每一个进程,系统会为它分配一个单独的进程空间,不同的进程有不同...
  • Linux进程间通信

    2017-05-20 12:17:47
    Linux进程间通信
  • 但它们还可以作为进程间通信或修改行为的一种方式,明确地由一个进程发送给另一个进程。一个信号的产生叫生成,接收到一个信号叫捕获。 二、信号的种类 信号的名称是在头文件signal.h中定义的,信号都以SIG开头,...
  • 本篇文章主要介绍了Linux进程间通信--使用信号的相关知识。具有很好的参考价值。下面跟着小编一起来看下吧
  • 进程间通信常见方式如下: 管道 FIFO 消息队列 信号量 共享内存 UNXI域套接字 套接字(Socket) 1. 管道 管道是一种古老的IPC通信形式。它有两个特点: 半双工,即不能同时在两个方向上传输数据。有的系统可能支持...

    0. 简介

    进程间通信常见方式如下:

    管道
    FIFO
    消息队列
    信号量
    共享内存
    UNXI域套接字
    套接字(Socket)

    1. 管道

    管道是一种古老的IPC通信形式。它有两个特点:

    • 半双工,即不能同时在两个方向上传输数据。有的系统可能支持全双工。
    • 只能在父子进程间。经典的形式就是管道由父进程创建,进程fork子进程之后,就可以在父子进程之间使用了。
      使用popen函数和pclose函数结合来执行系统命令,就用到了管道,它们声明如下:
    FILE *popen(const char *command,const char *type);
    int pclose(FILE *stream);
    

    2. FIFO

    FIFO也被称为命名管道,与管道不同的是,不相关的进程也能够进行数据交换。

    涉及FIFO操作主要函数为:

    int mkfifo(const char *path, mode_t mode);
    

    而FIFO也常常有以下两个用途:

    • 无需创建中间临时文件,复制输出流
    • 多客户-服务进程应用中,通过FIFO作为汇聚点,传输客户进程和服务进程之间的数据

    写进程代码如下:

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <fcntl.h>
    #define FIFO "/tmp/fifo"
    #define MAX_LEN 128
    int main(void)
    {
        int writeFd;
        char line[MAX_LEN] = {0};
        if(mkfifo(FIFO,S_IRUSR|S_IWUSR) < 0 && (errno != EEXIST))
        {
             perror("make fifo failed:");
             return -1;
        }
        /*关闭管道的读描述符*/
        writeFd = open(FIFO,O_WRONLY,0);
        /*向管道写入数据*/
        write(writeFd,"www.yanbinghu.com",sizeof("www.yanbinghu.com"));
        close(writeFd);
        return 0;
    }
    

    它先打开一个已知的FIFO,然后从FIFO中读取数据。两个没有亲缘关系的进程可以通过FIFO进行通信。

    3. 消息队列

    消息队列可以认为是一个消息链表,存储在内核中,进程可以从中读写数据。与管道和FIFO不同,进程可以在没有另外一个进程等待读的情况下进行写。另外一方面,管道和FIFO一旦相关进程都关闭并退出后,里面的数据也就没有了,但是对于消息队列,一个进程往消息队列中写入数据后退出,另外一个进程仍然可以打开并读取消息。消息队列与后面介绍的UNIX域套接字相比,在速度上没有多少优势。

    4. 信号量

    信号量是一个计数器,它主要用在多个进程需要对共享数据进行访问的时候。考虑这一的情况,不能同时有两个进程对同一数据进行访问,那么借助信号量就可以完成这样的事情。
    它的主要流程如下:

    检查控制该资源的信号量
    如果信号量值大于0,则资源可用,并且将其减1,表示当前已被使用
    如果信号量值为0,则进程休眠直至信号量值大于0
    也就是说,它实际上是提供了一个不同进程或者进程的不同线程之间访问同步的手段。

    5. 共享内存

    共享内存允许多个进程共享一个给定的存储区,由于它们是共享一块内存数据,因此其速度非常快。但是需要另外提供手段来保证共享内存的同步访问,例如它可以用到前面所提到的信号量来实现访问同步。

    6. UNIX域套接字

    UNIX域套接字和套接字很相似,但是它有更高的效率,因为它不需要执行协议处理,例如计算校验和,发送确认报文等等,它仅仅复制数据。

    当然,它也只适用于同一台计算机上的进程间通信。

    例如redis服务配置unixsocket启动后,通过redis-cli的-s参数就可以指定UNIX域套接字,连接到redis服务器。

    $ redis-cli -s /tmp/redis.sock
    redis /tmp/redis.sock> 
    

    它会比使用网络套接字的速度要快。

    Unix domain socket 或者 IPC socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信。与管道相比,Unix domain sockets 既可以使用字节流,又可以使用数据队列,而管道通信则只能使用字节流。Unix domain sockets的接口和Internet socket很像,但它不使用网络底层协议来通信。Unix domain socket 的功能是POSIX操作系统里的一种组件。

    Unix domain sockets 使用系统文件的地址来作为自己的身份。它可以被系统进程引用。所以两个进程可以同时打开一个Unix domain sockets来进行通信。不过这种通信方式是发生在系统内核里而不会在网络里传播。

    7. 网络套接字

    这个不用多说,它利用网络进行通信,与前面所提到的通信方式不同的是,它能用于不同计算机之间的不同进程间通信。

    网络套接字(英语:Network socket;又译网络套接字、网络接口、网络插槽)在计算机科学中是电脑网络中进程间资料流的端点。使用以网际协议(Internet Protocol)为通信基础的网络套接字,称为网际套接字(Internet socket)。因为网际协议的流行,现代绝大多数的网络套接字,都是属于网际套接字。

    定义
    系统内部接口(内部网络),接口描述符(抽象接口描述符)和接口地址之间的差别其实很细微,日常编程用的时候几乎不做区别。并且详细的网络接口有下面几种特征:

    (1)本地接口地址,由本地ip地址和(包括TCP,UDP)端口号
    (2)传输协议,例如TCP、UDP、raw IP协议,如果只是指定IP地址,那么TCP 53与UDP 53不是一个接口。

    示例:

    Socket socket = getSocket(type = "TCP")
    connect(socket, address = "1.2.3.4", port = "80")
    send(socket, "Hello, world!")
    close(socket)
    

    参考:

    1. Linux进程间通信方式有哪些?;
    2. wiki Unix域套接字;
    3. wiki 网络套接字
    展开全文
  • Linux进程间通信的方法和示例

    千次阅读 2019-08-07 13:08:56
    进程通信的概念 进程数据空间是相互独立的,不能相互访问的。但某些情况下进程之间需要互相通信,来完成系统的某项功能或交换数据。 进程通信的场景 1)数据传输:一个进程需要将它的数据发送给另一个进程,...

     

    进程通信的概念

            进程数据空间是相互独立的,不能相互访问的。但某些情况下进程之间需要互相通信,来完成系统的某项功能或交换数据。

    进程通信的场景

            1)数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间。

            2)共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。

            3)通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如通知进程退出)。

            5)进程控制:有些进程希望控制另一个进程的运行。

    进程通信的方式

    1、进程通信的方式

            1)无名管道(pipe)及有名管道(named pipe):无名管道可用于具有父进程和子进程之间的通信。有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

            2)信号(signal):信号用于通知接受进程有某种事件发生。

            3)消息队列(message):消息队列是消息的链接表,进程可以向队列中添加消息,其它的进程则可以读走队列中的消息。

            4)共享内存:使得多个进程可以访问同一块内存空间。

            5)信号灯(semaphore):也叫信号量,主要作为进程之间对共享资源加锁的手段。

            6)套接字(socket):可用于不同机器之间的进程间通信。

    2、应用经验

            管道和消息队列:太过时了,实在没什么应用价值,了解一下即可。

            信号灯(semaphore):我有十年没用过了,可能会有用,也是了解一下即可,不必深入学习。

            信号(signal):在信号章节中已详细介绍。

            套接字(socket):在TCP通讯章节中介绍。

            共享内存:应用场景不多,但还是有,本章节将介绍它。

            共享内存和信号灯的江湖地位本来是很高的,但是,随着网络带宽的增加和内存数据库技术的发展,共享内存的应用场景越来越少。但是,对于大型数据库系统来说,共享内存和信号灯仍极其重要。

            socket可以用于不同机器之间的进程通信,完全可以代替只能在同一机器的进程通信的管道和消息队列。

    共享内存的概念

            共享内存就是允许多个进程访问同一个内存空间。共享内存是在多个进程之间共享和传递数据最高效的方式。操作系统将不同进程之间共享内存安排为同一段物理内存,进程可以将共享内存连接到它们自己的地址空间中,如果某个进程修改了共享内存中的数据,其它的进程读到的数据也将会改变。

            共享内存并未提供锁机制,也就是说,在某一个进程对共享内存的进行读写的时候,不会阻止其它的进程对它的读写。如果要对共享内存的读写加锁,我们可以用共享内存自身的标记或信号灯。对普通程序员来说,对共享内存加锁的应用场景并不多见。

    共享内存的操作

            Linux中提供了一组函数用于操作共享内存,它们声明在头文件 sys/shm.h 中。

    1、shmget函数

            shmget函数用来获取或创建共享内存,它的声明为:

                    int shmget(key_t key, size_t size, int shmflg);

            参数key是共享内存的键值,是一个整数,typedef unsigned int key_t,是共享内存在系统中的编号,不同共享内存的编号不能相同,这一点由程序员保证。key用十六进制表示比较好。

            参数size是待创建的共享内存的大小,以字节为单位。

            参数shmflg是共享内存的访问权限,与文件的权限一样,0666|IPC_CREAT表示全部用户对它可读写,如果共享内存不存在,就创建一个共享内存。

    2、shmat函数

            把共享内存连接到当前进程的地址空间。它的声明如下:

                    void *shmat(int shm_id, const void *shm_addr, int shmflg);

            参数,shm_id是由shmget函数返回的共享内存标识。

            参数shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。

            参数shm_flg是一组标志位,通常为0。

            调用成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1.

    3、shmdt函数

            该函数用于将共享内存从当前进程中分离,相当于shmat函数的反操作。它的声明如下:

                    int shmdt(const void *shmaddr);

            参数shmaddr是shmat函数返回的地址。

            调用成功时返回0,失败时返回-1.

    4、shmctl函数

            删除共享内存,它的声明如下:

                    int shmctl(int shm_id, int command, struct shmid_ds *buf);

            参数shm_id是shmget函数返回的共享内存标识符。

            参数command填IPC_RMID。

            参数buf填0。

            解释一下,shmctl是控制共享内存的函数,其功能不只是删除共享内容,但其它的功能没什么用,所以不介绍了。

            注意,用root创建的共享内存,不管创建的权限是什么,普通用户无法删除。

    5、示例程序(book255.cpp)

        

           运行结果

          

           注意,程序第一次运行的时候,共享内存未创建,所以第一次运行程序的时候,共享内存中的内容为空。之后程序每次运行都能获取到上一次程序运行写入的内容。

    6、两个共享内存的操作命令

           用ipcs -m可以查看当前用户有读限权的共享内存,内容有键值(key),共享内存编号(shmid),创建者(owner),权限(perms),大小(bytes)。

           

           用ipcrm -m 共享内存编号,可以手工删除共享内存,如下:

          

     

    版权声明

    C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。

    来源:C语言技术网(www.freecplus.net

    作者:码农有道

    如果这篇文章对您有帮助,请点赞支持,或在您的博客中转发我的文章,谢谢!!!

    如果文章有错别字,或者内容有误,或其他的建议或意见,请您留言指正,非常感谢!!!

    展开全文
  • 主要介绍了Linux消息队列实现进程间通信实例详解的相关资料,需要的朋友可以参考下
  • 主要介绍了详解Linux进程间通信——使用信号量,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Linux进程间通信——管道通信

    千次阅读 多人点赞 2019-05-05 18:36:48
    1. 进程间通信概述 进程间通信(Inter-Process Communication, IPC)是指在两个或者多个不同得劲进程间传递或者交换信息,通过信息的传递建立几个进程间的联系,协调一个系统中的多个进程之间的行为。 1.1 进程间...

    1. 进程间通信概述

    进程间通信(Inter-Process Communication, IPC)是指在两个或者多个不同得劲进程间传递或者交换信息,通过信息的传递建立几个进程间的联系,协调一个系统中的多个进程之间的行为。
    1.1 进程间通信的工作原理
    进程与进程之间是相互独立的,各自运行在自己的虚拟内存中。要想在进程与进程间建立联系,需要通过内核,在内核中开辟一块缓冲区,两个进程的信息在缓冲区中进行交换或者传递。其原理如下图所示。
    在这里插入图片描述
    进程间通信原理是:进程A中的数据写入到内核中,进程B中的数据也写入到内核中,两者在内核中进行交换。交换后,进程A读取内核中的数据,进程B也读取内核中的数据,这样两个进程间交换数据的通信就完成了。两个进程通过内核建立了联系,那么交换数据、传递数据、发送事件等行为就都可以实现了。
    1.2 进程间通信的主要分类
    在Linux系统中,常见的进程间通信主要包括管道通信、共享内存通信、信号量通信、消息队列通信、套接口(SOCKET)通信和全双工通信。
    Linux系统除了支持信号和管道外,还支持SYSV(System V)子系统中的进程间通信机制。在SYSV的IPC机制中,包括共享内存、信号量、消息队列通信。

    2. 管道

    管道与命名管道是最基本的IPC机制之一。管道主要用于父子或者兄弟进程间的数据读写,命名管道则可以在无关联的进程间进行沟通传递数据。
    2.1 管道的基本定义
    所谓管道,就像生活中的煤气管道、下水管道等传输气体和液体的工具,而在进程通信意义上的管道就是传输信息或数据的工具。以下水管道为例,当从管道一端输送水流到另一端时,只有一个传输方向,不可能同时出现两个传输方向。在Linux系统中的进程通信中,管道这个概念也是如此,某一时刻只能单一方向传递数据,不能双向传递数据,这种工作模式就叫做半双工模式。半双工工作模式的管道通信是只能从一端写数据,从另一端读数据。

    2.2 管道创建和管道关闭
    管道由Linux系统提供的pipe()函数创建,该函数原型为:

    #include <unistd.h>
    int pipe(int filedes[2]);
    

    pipe()函数用于在内核中创建一个管道,该管道一端用于读取管道中的数据,另一端用于将数据写入管道。在创建一个管道后,会获得一对文件描述符,用于读取和写入,然后将参数数组filedes中的两个值传递给获取到的两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向写端。
    pipe()函数调用成功,返回值为0;否则返回-1,并且设置了适当的错误返回信息。此函数只是创建了管道,要想从管道中读取数据或者向管道中写入数据,需要使用read()和write()函数来完成。当管道通信结束后,需要使用close()函数关闭管道的读写端。

    2.3 pipe()函数实现管道通信
    (1)在父进程中调用pipe()函数创建一个管道,产生一个文件描述符filedes[0]指向管道的读端和另一个文件描述符filedes[1]指向管道的写端。
    (2)在父进程中调用fork()函数创建一个一模一样的新进程,也就是所谓的子进程。父进程的文件描述符一个指向读端,一个指向写端。子进程同理。
    (3)在父进程关闭指向管道写端的文件描述符filedes[1],在子进程中,关闭指向管道读端的文件描述符filedes[0]。此时,就可以将子进程中的某个数据写入到管道,然后在父进程中,将此数据读出来。
    过程如下图所示:
    在这里插入图片描述
    其程序代码如下:

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #define MAXSIZE 100
    
    int main()
    {
        int fd[2], pid, line;
        char message[MAXSIZE];
        /*创建管道*/
        if(pipe(fd) == -1)
        {
    	perror("create pipe failed!");
    	return 1;
        }
        /*创建新进程*/
        else if((pid = vfork()) < 0)
        {
    	perror("not create a new process!");
    	return 1;
        }
        /*子进程*/
        else if(pid == 0)
        {
    	close(fd[0]);
    	printf("child process SEND message!\n");
    	write(fd[1], "Hello Linux!",12); /*向文件中写入数据*/ 
        }
        else
        {
    	close(fd[1]);
    	printf("parent process RECEIVE message is:\n");
    	line = read(fd[0], message, MAXSIZE); /*读取消息,返回消息长度*/
    	write(STDOUT_FILENO,message,line); /*将消息写入终端*/
    	printf("\n");
    	wait(NULL);
    	_exit(0);
        }
        return 0;
    }
    
    

    结果:
    在这里插入图片描述
    管道特点:

    1. 只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork(),此后父子进程之间就可以应用该管道。
    2. 一般而言,进程退出,管道释放,所以管道的生命周期跟随进程。
    3. 一般而言,内核会对管道操作进行同步与互斥
    4. 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道。
      在这里插入图片描述

    3. 命名管道

    以上介绍的管道通信的方法有很多限制。受限制之一就是两个进程必须是相关联的进程。若是没有关系的进程间通信就要用命名管道。命名管道通常被称为FIFO。它作为特殊的设备文件存在于文件系统中。因此,在进程中可以使用open()和close()函数打开和关闭命名管道。

    3.1 创建一个命名管道
    · 命名管道可以从命令行上创建,命令行方法是使用下面这个命令:

    $ mkfifo filename
    

    · 也可以从程序里创建,相关函数:

    #include <sys/tyoes.h>
    #include <sys/stat.h>
    int mkfifo(const char* pathname, mode_t mode);
    

    该函数的参数pathname是一个文件的路径名,是创建的一个命名管道的文件名;参数mode是指文件的权限,文件权限取决于(mode&~umask)的值。
    使用mkfifo()函数创建的命名管道文件与前面介绍的管道通信相似,只是它们创建方式不同。访问命名管道文件与访问文件系统中的其他文件一样,都是需要首先打开文件,然后对文件进行读写数据。如果在命名管道文件中读取数据时,并没有其他进程向命名管道文件中写入数据,则会出现进程阻塞状态;如果在写入数据的同时,没有进程从命名管道中读取数据,也会出现进程阻塞状态。
    程序如下:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #define FIFO "/root/process/hello"
    
    int main()
    {
        int fd;
        int pid;
        char r_msg[BUFSIZ];
        if((pid = mkfifo(FIFO,0777))==-1) /*创建命名管道*/
        {
    	perror("create fifo channel failed!");
    	return 1;
        }
        else
        printf("create success!\n");
        fd = open(FIFO, O_RDWR);  /*打开命名管道*/
        if(fd == -1)
        {
    	perror("cannot open the FIFO");
    	return 1;
        }
        if(write(fd,"hello world", 12) == -1)  /*写入消息*/
        {
    	perror("write data error!");
    	return 1;
        }
        else
        printf("write data success!\n");
        if(read(fd, r_msg, BUFSIZ) == -1)  /*读取消息*/
        {
    	perror("read error!");
    	return 1;
        }
        else
        printf("the receive data is:  %s\n",r_msg);
        close(fd);   /*关闭文件*/
        return 0;
    }
    
    

    在这里插入图片描述
    通过以上代码,可以了解到使用mkfifo()函数创建命名管道并进行数据传递的过程:
    (1)用mkfifo()函数创建一个命名管道,命名管道文件路径为/root/process/hello
    (2)调用open()函数打开该命名管道文件,以读写的方式打开。
    (3)调用write()函数向文件写入信息"hello world", 同时调用read()函数读取该文件,输出到终端。
    (4)调用close()函数关闭打开的命名管道文件。

    展开全文
  • linux系统进程间通信英文版,里面详细介绍了linux环境下常用的进程间通信方式,shared memery, pipes, FIFO, semaphores, message queue, sockets, rpc
  • LINUX 环境进程间通信 LINUX 环境进程间通信全 目录 一Linux 环境进程间通信一管道及有名管道 3 1 管道概述及相 API 应用 3 1.1 管道相关的关键概念 3 1.2 管道的创建 3 1.3 管道的读写规则 3 1.4 管道应用实例 8 ...
  • Linux进程间通信方式汇总 目前已包含的方式 管道(PIPE) FIFO(有名管道) XSI消息队列 XSI信号量 XSI共享内存 POSIX信号量 域套接字(Domain Socket) 信号(Signal) 互斥量(Mutex) 其中信号(signal)和信号量(semaphore)...
  • linux 进程间通信

    2012-11-17 15:01:32
    Demo是实现进程间通信的实例当前大型进程间通信都是以本Demo为例实现的 本代码通过测试无误直接贴过去就能运行Linux下 SYSTEM V
  • Linux进程间通信.zip

    2019-07-02 21:18:14
    Linux进程间通信(fifo/pipe/mmap)后续将会完成进程间通信(消息队列/信号) 请关注

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 128,401
精华内容 51,360
关键字:

linux进程间通信

linux 订阅