通信方式分4大类:

管道通信:无名管道 有名管道
信号通信:发送 接收 和 处理
IPC通信:共享内存 消息队列 信号灯
socke 网络通信

用户空间      进程A     <----无法通信---->      进程B
-----------------|--------------------------------------|--------------
|            |
内核空间 |<-------------> 对象 <--------------->| ---------------------------------------------------------------------- //基于文件IO的思想
//open 打开或者创建一个文件,内核开辟一个buffer -->打开对象
//write 往buffer里面写
//read 从buffer读
//close 释放buffer

1. 进程间的管道通信

用户空间       进程A       <----无法通信---->       进程B
-----------------|--------------------------------------|--------------
    |             |
内核空间    |<-------------> 管道 <--------------->| ---------------------------------------------------------------------- 管道文件时一个特殊的文件,由队列来实现
open --> pipe
管道中的东西读完了,就删除了、
管道中如果没有东西可读,就会 读堵塞
管道中如果写满了,就会写阻塞

1.1 无名管道

无名管道用于父子进程带有亲缘关系的进程

#include <unistd.h>
int pipe(int fildes[]); //创建
//文件描述符 filds[0]-read--出队 filds[1]-write--入队 write(); //写
read(); //读
close(fd[]);
close(fd[]); ------------------------------
fd[]write fd[]read
------------------------------

小例子

int main()
{
int fd[]; //pipe的2个文件描述符
int ret;
ret = pipe(fd); //创建管道
if(ret < ){
perror("pipe");
return -;
}
printf("fd[0] = %d, fd[1] = %d\n",fd[],fd[]);
return ;
}
#include <stdio.h>
#include <string.h>
#include <unistd.h> int main(int argc, char const *argv[])
{
int fd[];
int ret;
const char *writebuf = "hello pipe";
char readbuf[] = {}; //1,创建pipe
ret = pipe(fd);
if(ret < )
{
perror("pipe");
return -;
}
printf("fd[0] = %d,fd[1] = %d\n",fd[],fd[]); //2.write
ret = write(fd[],writebuf,strlen(writebuf));
if(ret < ){
perror("write");
}
//2.read
ret = read(fd[],readbuf,);
if(ret < ){
perror("read");
return -;
} printf("read: %s\n",readbuf); //3.close
close(fd[]);
close(fd[]);
return ;
}

1.2 有名管道

  对于无名管道,pipe要在fork之前创建,这样fork的时候,会将fd[0]和fd[1]拷贝,这样两个进程就使用的是同2个设备描述符,如果pipe在fork之后创建,那个2个进程就会分别创建1个管道,操作的不是同一个管道文件,就没办法实行通信。

   也就是说,无名管道只能用于fork创建这样的父子进程, 如果无亲缘关系的进程,无名管道没办法进行通信,就只能使用有名管道。

  有名管道 即创建一个带有文件inode节点的管道文件 p, 该文件不占有内存空间,仅有一个文件节点, 当该节点被open时,才占用内存空间。

   mkfifo 只是在用户空间创建了一个管道文件,并非在内存空间创建管道,只有在open时,才在内存空间创建一个管道。

   注,有名管道两端成对打开时才会开始执行

#include <sys/types.h>
#include <sys/stat.h> int mkfifo(const char *path, mode_t mode); //文件路径 文件权限
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h> int main(int argc, char const *argv[])
{
int ret; //0=ok -1=failes ret = mkfifo("./fifo",); //创建管道文件 路径+权限
if(ret < ){
perror("mkfifo");
return -;
}
return ;
}

例子

fifo.c 创建有名管道文件

lude <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h> int main(int argc, char const *argv[])
{
int ret; ret = mkfifo("./fifo",); //创建管道文件 路径+权限
if(ret < ){
perror("mkfifo");
return -;
}
return ;
}

first.c 进程1

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h> int main(int argc, char const *argv[])
{
int fd;
int process_int = ; fd = open("./fifo",O_WRONLY); //注,有名管道两端成对打开时才会开始执行
if(fd < ){
perror("open");
return -;
}
puts("fifo open success."); for(int i=;i<;i++){
puts("我是第一个进程");
}
sleep();
process_int = ; write(fd,&process_int,);
while();
return ;
}

second.c 进程2

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h> int main(int argc, char const *argv[])
{
int fd;
int process_int = ; fd = open("./fifo",O_RDONLY); //注,有名管道两端成对打开时才会开始执行
if(fd < ){
perror("open");
return -;
}
puts("fifo open success."); read(fd,&process_int,);
while(process_int == ); for(int i=;i<;i++){
puts("我是第二个进程");
} while();
return ;
}

linux进程篇 (三) 进程间的通信1 管道通信的更多相关文章

  1. linux进程篇 (三) 进程间的通信2 信号通信

    2. 信号通信 用户空间 进程A <----无法通信----> 进程B -----------------|--------------------------------------|- ...

  2. linux进程篇 (三) 进程间的通信3 IPC通信

    3 IPC通信 用户空间 进程A <----无法通信----> 进程B -----------------|--------------------------------------|- ...

  3. c# c++通信--命名管道通信

    进程间通信有很多种,windows上面比较简单的有管道通信(匿名管道及命名管道) 最近做个本机c#界面与c++服务进行通信的一个需求.简单用命名管道通信.msdn都直接有demo,详见下方参考. c+ ...

  4. linux进程篇 (二) 进程的基本控制

    2. 进程的基本操作 接口函数 #include <unistd.h> //创建子进程 pid_t fork(void); //结束子进程 void exit(int status); / ...

  5. linux进程篇 (一) 进程的基本概念

    进程是系统资源分配的最小单位. 1.创建和执行 父进程通过 fork 系统调用创建子进程, 子进程被创建后,处于创建状态. linux为子进程配置数据结构,如果内存空间足够,子进程就在内核中就绪,成为 ...

  6. linux线程篇 (三) 线程的同步

    1 互斥量 pthreat_mutex_t mymutex; //1. 创建 初始化 int pthread_mutex_init(pthread_mutex_t *mutex, const pthr ...

  7. Linux基础篇三:文件系统

    /bin      实际上是  /usr/bin /sbin    实际上是  /usr/sbin /usr/bin 里面的命令其实是依赖  /lib64  或者    /lib32 ldd  /us ...

  8. 管道通信,王明学learn

    管道通信 一.通讯目的 1.数据传输 一个进程需要将数据发送给另一个进程. 2.资源共享 多个进程之间共享同样的资源. 3.通知事件 一个进程需要向另一个/组进程发送消息,通知它们发生了某事件. 4. ...

  9. C#命名管道通信

    C#命名管道通信 最近项目中要用c#进程间通信,以前常见的方法包括RMI.发消息等.但在Windows下面发消息需要有窗口,我们的程序是一个后台运行程序,发消息不试用.RMI又用的太多了,准备用管道通 ...

随机推荐

  1. npm install warning: no description; no repository field

    npm install 报错:warning no description; no repository field 开始以为必须npm init,npm init在git bash(win7)里,还 ...

  2. Linux入门-2 VIM基础

    启动与退出 模式 进入插入模式 命令 删除.复制.粘贴 光标控制 查找与替换 EX模式 启动与退出 vim只启动vim vim <filename>打开文件,如果不存在则新建 模式 Nor ...

  3. Sandworm Attack小结

    这个漏洞刚出来时就分析过,当时大致弄明白了原理,但对很多细节和原理还是一知半解.后来开始找工作……今天终于有时间来把欠的这部分功课补上. 这个漏洞网上的各种中英文分析已经很多了,因此这里我只根据自己的 ...

  4. oam系统安装,windows操作系统注册列表影响系统安装

    windows注册列表可能会影响到系统的安装,本次安装oam10g版本,安装后没有问题,但是在配置oam和weblogic portal单点登录时在weblogic portal中访问oid和oam的 ...

  5. ZT-Android深入浅出之Binder机 制

    转贴 不是原创! Android深入浅出之Binder机 制 一说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交 ...

  6. [原]零基础学习视频解码之FFMpeg中比较重要的函数以及数据结构

    在正式开始解码练习前先了解下关于FFmpeg中比较重要的函数以及数据结构. 1. 数据结构:  (1) AVFormatContext  AVFormatContext是一个贯穿始终的数据结构,很多函 ...

  7. Redis口令设置

    ./redis-cli -h 192.168.128.131 -p 6379 #指定IP和端口启动对应的Redis服务 config set requirepass yourPassword #设置令 ...

  8. 隐藏C#的TabControl控件的选项卡TabPage

    在使用TabControl控件时,希望隐藏其中某个选项卡(即TabPage).TabPage类明明提供了一个Hide方法,用在代码中却没有任何效果,甚是奇怪.无奈之余,只好考虑另辟途径.方法一:设置该 ...

  9. PAT——1064. 朋友数(set用法)

    如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”.例如123和51就是朋友数,因为1+2+3 = 5+1 = 6,而6就是它们的朋友证号.给定一些整数,要求 ...

  10. HDU 1006 Tick and Tick(时钟,分钟,秒钟角度问题)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1006 Tick and Tick Time Limit: 2000/1000 MS (Java/Oth ...