进程间通信,无名管道pipe,有名管道mkfifo,信号的基础概念,signal函数

本文主要是介绍进程间通信,无名管道pipe,有名管道mkfifo,信号的基础概念,signal函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我要成为嵌入式高手之2月28日Linux高编第十一天!!

学习笔记 

进程间通信

总共6种通信方法,主要是前五种方式

第一种方式:管道

一、无名管道

只能用于具有亲缘关系的进程间通信

pipe

#include <unistd.h>

int pipe(int pipefd[2]);

功能:创建一个无名管道

参数:

        pipefd[0]:读

        pipefd[1]:写

返回值:成功返回0;失败返回-1

#include "head.h"int main(void)
{pid_t pid;int fd[2];int ret;char tmpbuff[4096];ret = pipe(fd);if (ret == -1){perror("fail to pipe");return -1;}pid = fork();if (pid == -1){perror("fail to fork");return -1;}if (pid == 0){strcpy(tmpbuff, "hello world!");write(fd[1], tmpbuff, strlen(tmpbuff));}else if (pid > 0){read(fd[0], tmpbuff, sizeof(tmpbuff));//read有等待作用,若文件标识符内没有可读内容,会等待到有可读内容printf("tmpbuff = %s\n", tmpbuff);}close(fd[0]);close(fd[1]);return 0;
}

 

无名管道的特性:

1、管道中至少有一个写端:

        读取数据时如果有数据直接读取;管道中没有数据,阻塞等待直到有数据写入,然后读出,继续向后执行 。

2、管道中没有写端:

        读取数据时,如果管道中有数据直接读取,管道中没有数据不阻塞等待直接向下执行

3、管道中至少有一个读端:

        写入数据时,如果管道中没有存满则直接写入,如果管道中存满则阻塞等待,直到有数据读出才继续写入

4、管道中没有读端:

        写入数据时,会产生管道破裂的错误,导致程序崩溃

二、有名管道

操作方式:

        打开管道文件(open)--->读写(read,write)管道文件--->关闭(close)管道文件

特性:有名管道必须读写两端同时加入才能继续向下执行

1、mkfifo

#include <sys/types.h>
#include <sys/stat.h>

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

功能:创建一个管道文件

参数:

        pathname:管道文件的路径(名字包含在路径里)

        mdoe:权限(0777、0664)

返回值:成功返回0,失败返回-1;

练习:编写两个进程A B, A给B发送一条消息,B收到消息打印后给A回复一条消息

注:在接收函数之前都加入memset

#include "head.h"int main(void)
{int fatob = 0;int fbtoa = 0;char tmpbuff[1024] = {0};mkfifo("/tmp/ATOB", 0777);mkfifo("/tmp/BTOA", 0777);fatob = open("/tmp/ATOB", O_WRONLY);if (fatob == -1){perror("fail to open1");return -1;}fbtoa = open("/tmp/BTOA", O_RDONLY);if (fbtoa == -1){perror("fail to open2");return -1;}while (1){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);write(fatob, tmpbuff, strlen(tmpbuff));memset(tmpbuff, 0, sizeof(tmpbuff));read(fbtoa, tmpbuff, sizeof(tmpbuff));printf("RECV:  %s\n", tmpbuff);}close(fatob);close(fbtoa);return 0;
}
#include "head.h"int main(void)
{int fatob = 0;int fbtoa = 0;char tmpbuff[1024] = {0};mkfifo("/tmp/ATOB", 0777);mkfifo("/tmp/BTOA", 0777);fatob = open("/tmp/ATOB", O_RDONLY);if (fatob == -1){perror("fail to open1");return -1;}fbtoa = open("/tmp/BTOA", O_WRONLY);if (fbtoa == -1){perror("fail to open2");return -1;}while (1){memset(tmpbuff, 0, sizeof(tmpbuff));read(fatob, tmpbuff, sizeof(tmpbuff));printf("RECV:  %s\n", tmpbuff);memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);write(fbtoa, tmpbuff, strlen(tmpbuff));}close(fatob);close(fbtoa);return 0;
}

 进阶难版

#include "head.h"pthread_t tid1;
pthread_t tid2;void *Write(void *arg)
{int fatob = 0;char tmpbuff[1024] = {0};while (1){mkfifo("/tmp/ATOB", 0777);fatob = open("/tmp/ATOB", O_WRONLY);if (fatob == -1){perror("fail to open1");return NULL;}memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);write(fatob, tmpbuff, strlen(tmpbuff));if (!strcmp(tmpbuff, ".quit")){break;}close(fatob);}pthread_cancel(tid2);return NULL;
}void *Read(void *arg)
{int fbtoa;char tmpbuff[1024] = {0};while (1){mkfifo("/tmp/BTOA", 0777);fbtoa = open("/tmp/BTOA", O_RDONLY);if (fbtoa == -1){perror("fail to open2");return NULL;}memset(tmpbuff, 0, sizeof(tmpbuff));read(fbtoa, tmpbuff, sizeof(tmpbuff));if (!strcmp(tmpbuff, ".quit")){break;}printf("RECV:  %s\n", tmpbuff);close(fbtoa);}pthread_cancel(tid1);return NULL;
}int main(void)
{int ret1 = 0;int ret2 = 0;ret1 = pthread_create(&tid1, NULL, Write, NULL);if (ret1 != 0){perror("fail to tid1");return -1;}ret2 = pthread_create(&tid2, NULL, Read, NULL);if (ret2 != 0){perror("fail to tid2");return -1;}pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0;
}
#include "head.h"pthread_t tid1;
pthread_t tid2;void *Write(void *arg)
{int fbtoa = 0;char tmpbuff[1024] = {0};while (1){mkfifo("/tmp/BTOA", 0777);fbtoa = open("/tmp/BTOA", O_WRONLY);if (fbtoa == -1){perror("fail to open1");return NULL;}memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);write(fbtoa, tmpbuff, strlen(tmpbuff));if (!strcmp(tmpbuff, ".quit")){break;}close(fbtoa);}pthread_cancel(tid2);return NULL;
}void *Read(void *arg)
{int fatob;char tmpbuff[1024] = {0};while (1){mkfifo("/tmp/ATOB", 0777);fatob = open("/tmp/ATOB", O_RDONLY);if (fatob == -1){perror("fail to open2");return NULL;}memset(tmpbuff, 0, sizeof(tmpbuff));read(fatob, tmpbuff, sizeof(tmpbuff));if (!strcmp(tmpbuff, ".quit")){break;}printf("RECV:  %s\n", tmpbuff);close(fatob);}pthread_cancel(tid1);return NULL;
}int main(void)
{int ret1 = 0;int ret2 = 0;ret1 = pthread_create(&tid1, NULL, Write, NULL);if (ret1 != 0){perror("fail to tid1");return -1;}ret2 = pthread_create(&tid2, NULL, Read, NULL);if (ret2 != 0){perror("fail to tid2");return -1;}pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0;
}

第二种方式:信号

信号用来实现内核层和用户层信息的交互,也可以用来实现进程间通信

一、信号的种类

kill -l来查看

1) SIGHUP(挂起)     

2) SIGINT(中断)     

3) SIGQUIT(退出)     

4) SIGILL    

5) SIGTRAP

6) SIGABRT(产生异常)     

7) SIGBUS(总线错误)     

8) SIGFPE    

9) SIGKILL(杀死信号)   

10) SIGUSR1

11) SIGSEGV(段错误)   

12) SIGUSR2    

13) SIGPIPE(管道破裂)   

14) SIGALRM(定时时间到了)   

15) SIGTERM

16) SIGSTKFLT    

17) SIGCHLD(一个子进程结束,给父进程发送的信号)   

18) SIGCONT(让进程继续执行)   

19) SIGSTOP(让进程挂起)   

20) SIGTSTP(让进程挂起)

21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ

26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO(异步IO)    30) SIGPWR

31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3

38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    

42) SIGRTMIN+8    43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    

46) SIGRTMIN+12    47) SIGRTMIN+13    48) SIGRTMIN+14    49) SIGRTMIN+15    

50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-12    53) SIGRTMAX-11    

54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7

58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    

62) SIGRTMAX-2    63) SIGRTMAX-1    64) SIGRTMAX    

所有的信号都可以让进程结束

二、信号处理方式

1、缺省:

        按照系统默认的方式处理

2、忽略:

        不响应信号

3、捕捉:

        按照自己设定的方式处理信号

注意:

        9号信号(杀死)和19号信号(暂停)不可被忽略和捕捉,即只能按照缺省的方式处理

可键入:

        SIGINT:ctrl + c

        SIGQUIT:ctrl + \

        SIGTSTP:ctrl + z

4、signal

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

功能:改变信号的处理方式

参数:

        signum:信号的编号

        handler:信号的处理方式

                SIG_IGN        忽略处理

                SIG_DFL        缺省处理

                函数首地址     捕捉处理

返回值:

        成功返回之前处理函数的首地址

        失败返回SIG_ERR

练习:

#include "head.h"void handler1(int signo)
{printf(" SIGINT信号来了!\n");return;
}void handler2(int signo)
{printf(" SIGQUIT信号来了!\n");return;
}void handler3(int signo)
{printf(" SIGTSTP信号来了!\n");return;
}int main(void)
{signal(SIGINT, handler1);signal(SIGQUIT, handler2);signal(SIGTSTP, handler3);while (1){}return 0;
}

这篇关于进程间通信,无名管道pipe,有名管道mkfifo,信号的基础概念,signal函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/761010

相关文章

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

Windows的CMD窗口如何查看并杀死nginx进程

《Windows的CMD窗口如何查看并杀死nginx进程》:本文主要介绍Windows的CMD窗口如何查看并杀死nginx进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows的CMD窗口查看并杀死nginx进程开启nginx查看nginx进程停止nginx服务

全屋WiFi 7无死角! 华硕 RP-BE58无线信号放大器体验测评

《全屋WiFi7无死角!华硕RP-BE58无线信号放大器体验测评》家里网络总是有很多死角没有网,我决定入手一台支持Mesh组网的WiFi7路由系统以彻底解决网络覆盖问题,最终选择了一款功能非常... 自2023年WiFi 7技术标准(IEEE 802.11be)正式落地以来,这项第七代无线网络技术就以超高速

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

Java进程CPU使用率过高排查步骤详细讲解

《Java进程CPU使用率过高排查步骤详细讲解》:本文主要介绍Java进程CPU使用率过高排查的相关资料,针对Java进程CPU使用率高的问题,我们可以遵循以下步骤进行排查和优化,文中通过代码介绍... 目录前言一、初步定位问题1.1 确认进程状态1.2 确定Java进程ID1.3 快速生成线程堆栈二、分析

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

java中BigDecimal里面的subtract函数介绍及实现方法

《java中BigDecimal里面的subtract函数介绍及实现方法》在Java中实现减法操作需要根据数据类型选择不同方法,主要分为数值型减法和字符串减法两种场景,本文给大家介绍java中BigD... 目录Java中BigDecimal里面的subtract函数的意思?一、数值型减法(高精度计算)1.

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以