进程间的通信(Linux)
目录
1、管道
(1)无名管道
1)无名管道的创建 --pipe()
2)无名管道的读写特性
(2)、有名管道
2、信号
(1)常用信号
(2)信号相关指令
(3)信号相关接口函数 -- kill
(4)定时器
(5)捕获信号 -- signal
进程间通信机制:
unix继承:管道、信号
system V IPC对象:共享内存、消息队列、信号灯集
套接字
1、管道
管道分为无名管道和有名管道 -- 区别在于创建的管道能否在文件系统中可见
(1)无名管道
特点:
1、在创建之后在文件系统中不可见
2、以半双工的方式进行通信
3、拥有固定的读端和写端
4、只能用于具有亲缘关系的进程间通信
1)无名管道的创建 --pipe()
#include <unistd.h>int pipe(int pipefd[2]);
参数:pipefd:存放无名管道读端和写端的数组首地址pipefd[0] -- 读端pipefd[1] -- 写端
返回值:成功返回0,失败返回-1
练习:在一个进程中创建一个子进程,子进程从键盘获取数据,父进程打印输出
代码示例:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>int main(int argc, char *argv[])
{int fd[2] = {0};//定义无名管道读写端的数组int ret = pipe(fd);//创建无名管道if(ret < 0){perror("pipe");exit(-1);}pid_t pid = fork();if(pid < 0){perror("fork");exit(-1);}if(pid == 0)//子进程{while(1){char buf[64] = {0};fgets(buf,64,stdin);buf[strlen(buf)-1] = '\0';write(fd[1],buf,strlen(buf));}exit(0);}else//父进程{while(1){char buf1[64] = {0};memset(buf1,0,64);read(fd[0],buf1,64);printf("%s\n",buf1);}}wait(NULL);exit(0);return 0;
}
运行结果:
2)无名管道的读写特性
读特性:
写端存在:如果管道有数据,返回读到的字节数
如果管道无数据,阻塞
写端不存在:如果管道有数据,返回读到的字节数
如果管道无数据,返回0
写特性:
读端存在:如果管道有空间,返回写入的字节数
如果管道无空间,阻塞,直到有空间为止
读端不存在:
无论管道是否有空间,管道破裂(向进程发送管道破裂信号,结束进程)
练习:1、计算无名管道空间大小
2、验证管道破裂
代码示例:
1、
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char *argv[])
{int fd[2];int ret = pipe(fd);if(ret < 0){perror("pipe");exit(-1);}int size = 0,m = 0;while(1){char buf[1024] = {0};size_t m = write(fd[1],buf,1024);//往管道里写数据,返回字节数size = size + m;printf("%d\n",size);}return 0;
}
2、
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>int main(int argc, char *argv[])
{ int pfd[2] = {0};int ret = pipe(pfd); //创建无名管道if(ret < 0){perror("pipe");exit(-1);}close(pfd[0]); //关闭无名管道的读端pid_t pid = fork(); //创建子进程if(pid == 0){write(pfd[1], "hello", 5);sleep(5);}else{int status;wait(&status);printf("%d %d %d\n", WIFEXITED(status),WIFSIGNALED(status),WTERMSIG(status));exit(0);}return 0;
}
运行结果:
(2)、有名管道
有名管道创建之后会在文件系统中以管道文件的形式存在
有名管道可以用于任意两个进程之间的通信,没有固定的读端和写端
(1)有名管道的创建 -- mkfifo
#include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);参数:pathname:创建管道文件的文件名mode:创建管道文件的权限
返回值:成功返回0,失败返回-1
练习:创建一个有名管道,一个进程向管道中输入数据,另一个进程输出数据
1、创建有名管道
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{ int ret = mkfifo("fifo", 0664);if(ret < 0){perror("mkfifo");exit(-1);}return 0;
}
2、创建进程
进程1:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char *argv[])
{ int fd = open("fifo", O_RDONLY);if(fd < 0){perror("open");exit(-1);}printf("open fifo ok!\n");char buf[64] = {0};while(1){memset(buf, 0, 64);read(fd, buf, 64);printf("%s\n", buf);}close(fd);return 0;
}
进程2:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char *argv[])
{ int fd = open("fifo", O_WRONLY);if(fd < 0){perror("open");exit(-1);}printf("open fifo ok!\n");char buf[64] = {0};while(1){fgets(buf, 64, stdin);buf[strlen(buf)-1] = '\0';write(fd, buf, strlen(buf));}close(fd);return 0;
}
2、信号
信号:是中断在软件层次上的一种模拟
信号的处理方式:
默认处理
忽略
捕获信号
(1)常用信号
(2)信号相关指令
kill -l :查看当前系统中的所有信号
kill -信号编号 进程号:向指定进程发送对应编号的信号
例:
kill -9 1234:向进程1234发送信号9
kill -9 -1234:向进程组1234发送信号9
kill -9 -1 :向除了init进程以外的其他所有进程发送信号9
(3)信号相关接口函数 -- kill
#include <sys/types.h>#include <signal.h>int kill(pid_t pid, int sig);参数:pid:指定进程号sig:指定信号
返回值:成功返回0,失败返回-1;-------------------------------------------------#include <signal.h>int raise(int sig);参数:sig:指定信号返回值:成功返回0,失败返回非零值
(4)定时器
定时时间到时,当前进程会接受到编号为14的信号 -- SIGARLM
一个进程中最多只能存在一个定时器
定时器相关函数 -- alarm
#include <unistd.h>unsigned int alarm(unsigned int seconds);参数:seconds:定时秒数
返回值:成功返回0或者上个定时器定时剩余的时间-------------------------------------------------#include <unistd.h>int pause(void);
功能:阻塞在当前位置,等待定时结束
(5)捕获信号 -- signal
#include <signal.h>typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);参数:signum:指定信号handler:信号处理函数SIG_IGN:选择以忽略方式处理指定信号SIG_DFL:选择以默认方式处理指定信号
练习:创建一个子进程,子进程结束时,父进程提示子进程退出信息
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void func(int num);
int main(int argc, char *argv[])
{ pid_t pid = fork();if(pid == 0){printf("aaaaaaaa\n");exit(0);}else{signal(17, func);while(1){printf("bbbbbbbbbbb\n");sleep(1);}}return 0;
} void func(int num)
{printf("child leave!\n");raise(9);
}
进程间的通信(Linux)相关推荐
- linux下进程间管道通信,Linux下进程间通信方式-管道
本文关键字: linux 管道通信,linux 进程通信方式,无名管道,有名管道 管道是Linux中进程间通信的一种方式,它把一个程序的输出直接连接到另一个程序的输入.Linux的管道主要包括两种:无 ...
- linux+Qt 下利用D-Bus进行进程间高效通信的三种方式
linux+Qt 下利用D-Bus进行进程间高效通信的三种方式 原文链接: https://www.cnblogs.com/wwang/archive/2010/10/27/1862552.html ...
- Linux系统编程(三)进程间的通信
Linux系统编程(三)进程间的通信 一.为什么需要进程之间的通信(IPC)? 二.管道 1.概念 2.特质 3.原理 4.局限性 5.代码 2.读入数据 三.共享存储映射 注意事项 父子进程通信 一 ...
- 命名管道(FIFO) Linux进程进程间的通信之命名管道(FIFO)
Linux进程进程间的通信之命名管道(FIFO) 命名管道(FIFO),它和一般的管道一样.都是作为中间的邮递员来实现两个进程间的通信交流. 命名管道(FIFO)有几个特点: 1.命名管道(FIFO) ...
- Linux之本地进程间Socket通信
文章目录 一.Sokcet 二.Sokcet API (一).sockaddr 结构: (二).struct socketaddr_in : (三).Struct socketaddr_un (四). ...
- 深刻理解 Linux 进程间七大通信(IPC)
前言 网络编程是 Linux C/C++的面试重点,今天我就来聊一聊进程间通信的问题,文章末尾列出了参考资料,希望帮助到大家. 篇幅有点长,希望大家耐心阅读. Linux 下的进程通信手段基本上是从 ...
- 进程间的通信之1-----管道
进程间的通信之1-----管道 1.标准流管道 像文件操作有标准 io 流一样, 管道也支持文件流模式. 用来创建连接到另一进程的管道, 是通过函数 popen 和 pclose. 函数原型: #in ...
- 进程间的通信——共享内存
下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...
- 网络编程之 进程间的通信之管道的使用
如何使用管道是进程间通信的关键 博主先声明一下,关于处理进程创建以及销毁的方法. "子进程究竟何时终止????调用waitpid函数后还要无休止的等待子进程终止吗???&quo ...
- python进程间通信时间开销_python 进程间的通信
python3,进程间的通信 本文来源于python 3.5版本的官方文档 multiprocessing模块为进程间通信提供了两种方法: 1.进程队列queue The Queue class is ...
最新文章
- [BZOJ2693]jzptab
- python程序员搞笑段子_程序员才能看得懂的段子,内含表情包,吃饭的时候别点!...
- C++ 输出当前所在的路径
- jQuery选择器介绍:基本选择器、层次选择器、过滤选择器、表单选择器
- 13.7.深入理解jstack日志
- java安卓获取mac_android开发分享以编程方式获取Android设备的MAC
- 借助大数据进行社交媒体营销,企业们得这么玩!
- python实现模糊搜索_Python 代码实现模糊查询
- Python遗传算法解决作业调度问题(JSP)
- 360屏保壁纸android,“如何删除屏保和壁纸”的解决方案
- Q 系列PLC ST 语言编程笔记
- java毕业设计德云社票务系统Mybatis+系统+数据库+调试部署
- Ubuntu 出现/usr/bin/ld: cannot find -lXp的问题
- 哪吒之魔童降世视听语言影评_《哪吒之魔童降世》观后感精彩影评5篇450字
- Excel怎么转换成PDF?这两种转换方法看到就是赚到
- 腾讯云服务器获取root权限(ubuntu系统)
- 【Python 常用英文单词】——总结Python常用的英文单词 最全版
- 拼团返利电商系统(拼返系统)v2.6
- curl可以访问但是requests就返回安全验证
- Android WLAN框架