重头开始嵌入式第二十六天(Linux系统编程 进程间通信 IPC)

目录

IPC 进程间通信

1.管道通信

管道的特性

使用流程

无名管道

1.创建并打开管道:

2.无名管道的读写:

3.关闭管道: close();

4.使用例子:

有名管道

1、创建:mkfifo

2、打开有名管道 open

3、管道的读写: 文件IO

4、关闭管道:

5、卸载管道:remove();


IPC 进程间通信

进程间通信(Inter-Process Communication,简称 IPC)是指在不同进程之间进行数据交换、消息传递和资源共享的机制。
 
常见的 IPC 方式包括:
 
1. 管道(Pipe):分为无名管道和有名管道。无名管道只能在具有亲缘关系的进程间使用,而有名管道可在无亲缘关系的进程间通信。
2. 消息队列(Message Queue):消息的链表,存放在内核中并由消息队列标识符标识。
3. 共享内存(Shared Memory):多个进程可以访问同一块物理内存区域,实现快速的数据交换,但需要同步机制来协调访问。
4. 信号量(Semaphore):用于实现进程间的互斥与同步。
5. 套接字(Socket):可用于不同主机上的进程间通信,也可用于同一主机上的进程间通信。
 
进程间通信在多进程和多线程编程中起着至关重要的作用,使得不同的进程能够协同工作,完成复杂的任务。

1.管道通信

管道的特性

管道具有以下特性:
 
1. 半双工通信:数据只能在一个方向上流动。如果要实现双向通信,需要建立两个管道。
2. 只能在具有亲缘关系(如父子进程)的进程间使用:通常是父进程创建管道,然后创建子进程,子进程会继承父进程的文件描述符,从而实现通过管道通信。
3. 数据是字节流形式:管道中的数据没有固定的格式或消息边界,就像一个连续的字节流。
4. 管道的容量有限:通常是一个有限的缓冲区大小,如果写入的数据超过了缓冲区的容量,写进程会被阻塞,直到读进程读取数据腾出空间。64k
5. 管道是基于文件描述符的:通过对文件描述符进行读写操作来实现数据的传递。
6. 生命周期随进程:如果参与通信的进程结束,管道也会被销毁。
7.管道破裂,读端关闭,写管道。

使用流程

无名管道

创建管道-读写管道-关闭管道

1.创建并打开管道:

 pipe函数

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

功能:创建并打开一个无名管道
参数:pipefd[0] ==>无名管道的固定读端
  pipefd[1] ==>无名管道的固定写端
返回值:成功 0
失败 -1;

注意事项:
1、无名管道的架设应该在fork之前进行。


2.无名管道的读写:

===》文件IO的读写方式。
读: read()
写: write()


3.关闭管道: close();

4.使用例子:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>              /* Obtain O_* constant definitions */
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
    int pipefd[2]={0};
    int ret = pipe(pipefd);
    if(-1 == ret)
    {
        perror("pipe");
        return 1;
    }

    pid_t pid = fork();
    if(pid>0)
    {
        close(pipefd[0]);
        sleep(3);
        char buf[50]="hello,child";
        write(pipefd[1],buf,strlen(buf));
    }
    else if(0 == pid)
    {
        close(pipefd[1]);
        char buf[50]={0};
        read(pipefd[0],buf,sizeof(buf));
        printf("father :%s\n",buf);
    }
    else 
    {
        perror("fork");
        return 1;
    }
    return 0;
}


有名管道

有名管道===》fifo ==》有文件名称的管道。
  文件系统中可见

框架:
创建有名管道 ==》打开有名管道 ==》读写管道
==》关闭管道  ==》卸载有名管道

 


1、创建:mkfifo

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

功能:在指定的pathname路径+名称下创建一个权限为
      mode的有名管道文件。
参数:pathname要创建的有名管道路径+名称
  mode  8进制文件权限。
返回值:成功 0
失败  -1;



2、打开有名管道 open


注意:该函数使用的时候要注意打开方式,
因为管道是半双工模式,所有打开方式直接决定
当前进程的读写方式。
一般只有如下方式:
int fd-read = open("./fifo",O_RDONLY); ==>fd 是固定读端
int fd-write = open("./fifo",O_WRONLY); ==>fd 是固定写端
不能是 O_RDWR 方式打开文件。
不能有 O_CREAT 选项,因为创建管道有指定的mkfifo函数
 


3、管道的读写: 文件IO


读: read(fd-read,buff,sizeof(buff));
写: write(fd-write,buff,sizeof(buff));


4、关闭管道:

close(fd);


5、卸载管道:remove();

int unlink(const char *pathname);

功能:将指定的pathname管道文件卸载,同时
  从文件系统中删除。
参数: ptahtname 要卸载的有名管道 
返回值:成功 0
失败  -1;

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值