重头开始嵌入式第二十七天(Linux系统编程 信号通信)

2024-08-27 02:28

本文主要是介绍重头开始嵌入式第二十七天(Linux系统编程 信号通信),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

进程间通信 ===》

1.信号通信

1.信号的五种类型:

2.kill

1、信号  kill  -l  ==>前32个有具体含义的信号

3.信号注册函数原型:

1.自定义信号处理:

2、在所有的信号中有如下两个特列:

 2.共享内存  信号量集

1.key创建方式有三种:

共享内存 ===》效率最高的进程间通信方式

1、申请对象:

2.映射对象:shmat()

3.读写共享内存:类似堆区内存的直接读写:

4.撤销映射:shmdt

5.删除对象:shmctl

3.IPC对象之信号量集 ==>sem ===》为了解决共享内存的临界资源访问

1、申请信号量  semget()

2、pv操作;semop


进程间通信 ===》

1.信号通信


应用:异步通信,中断。
1~64;32应用编程。
如何响应:

1.信号的五种类型:


 Term        Default action is to terminate the process.
 Ign            Default action is to ignore the signal.
 Core   Default action is to  terminate  the  process  and  dump  core  (see core(5)).
 Stop   Default action is to stop the process.
 Cont   Default  action  is  to  continue  the  process  if  it is currently stopped.

2.kill

原型:kill      -xx     xxxx
发送进程  信号    接收进程
kill -9 1000
a.out  9 1000
1、发送端

函数原型:

#include <sys/types.h>
#include <signal.h>int kill(pid_t pid, int sig);


功能:通过该函数可以给pid进程发送信号为sig的系统信号。
参数:pid 要接收信号的进程pid
  sig 当前程序要发送的信号编号 《=== kill  -l
返回值:成功 0
失败  -1;

1、信号  kill  -l  ==>前32个有具体含义的信号

以下是前 32 个有具体含义的信号:

1. SIGHUP:终端挂起或者控制进程终止。

2. SIGINT:中断信号,通常由用户按下 Ctrl+C 产生。

3. SIGQUIT:退出信号,通常由用户按下 Ctrl+\ 产生。

4. SIGILL:非法指令信号。

5. SIGTRAP:跟踪陷阱信号。

6. SIGABRT:异常终止信号,通常由调用 abort 函数产生。

7. SIGBUS:总线错误信号。

8. SIGFPE:浮点异常信号。

9. SIGKILL:立即终止信号,无法被捕获或忽略。

10. SIGUSR1:用户定义信号 1。

11. SIGSEGV:段错误信号。

12. SIGUSR2:用户定义信号 2。

13. SIGPIPE:管道破裂信号。

14. SIGALRM:闹钟信号。

15. SIGTERM:终止信号,可以被进程捕获并进行一些清理操作后再终止。

16. SIGSTKFLT:协处理器栈错误信号。

17. SIGCHLD:子进程状态改变信号。

18. SIGCONT:继续执行被暂停的进程。

19. SIGSTOP:停止信号,无法被捕获或忽略。

20. SIGTSTP:终端停止信号,通常由用户按下 Ctrl+Z 产生。

21. SIGTTIN:后台进程从终端读取数据时收到的信号。

22. SIGTTOU:后台进程向终端写数据时收到的信号。

23. SIGURG:紧急情况信号,通知有紧急数据在套接字上。

24. SIGXCPU:超过 CPU 时间限制信号。

25. SIGXFSZ:超过文件大小限制信号。

26. SIGVTALRM:虚拟定时器信号。

27. SIGPROF:性能分析定时器信号。

28. SIGWINCH:窗口大小改变信号。

29. SIGIO:异步 I/O 信号。

30. SIGPWR:电源故障信号。

31. SIGSYS:系统调用错误信号。

32. SIGRTMIN:实时信号最小值。

3.信号注册函数原型:


 
 void ( *signal(int signum, void (*handler)(int)) ) (int);


 typedef void (*sighandler_t)(int);
 ===》void (*xx)(int); == void fun(int);
 ===》xx是 void fun(int) 类型函数的函数指针
 ===》typedef void(*xx)(int)   sighandler_t; ///错误
  typedef int   myint;

 ===>sighandler_t signal(int signum, sighandler_t handler);
 ===> signal(int sig, sighandler_t fun);
 ===> signal(int sig, xxx fun);
 ===>fun 有三个宏表示:

SIG_DFL 表示默认处理
   SIG_IGN 表示忽略处理
   fun     表示自定义处理

1.自定义信号处理:


1、必须事先定义自定义函数,必须是如下格式:
void fun(int sig)  sig 接收到的信息编号
{

}


2、在所有的信号中有如下两个特列:


10 SIGUSR1
12 SIGUSR2
专门预留给程序员使用的未定义信号。

 2.共享内存  信号量集

shm,sem,msg
system v :  共享内存  信号量集

IPC对象操作通用框架:
0x  ftok
key值 ==> 申请 ==》读写 ==》关闭 ==》卸载



key值:唯一键值


1.key创建方式有三种:



1、IPC_PRIVATE 固定的私有键值,其值等于 0x0
一般用于有亲缘关系的进程间使用。

2、ftok()创建临时键值。
#include <sys/types.h>
#include <sys/ipc.h>
"/etc" '!'
key_t ftok(const char *pathname, int proj_id);
功能:通过该函数可以将pathname指定的路径用来以
  proj_id生成唯一的临时键值。
参数:pathname 路径+名称===》任意文件,只要不会
  被删除重建即可。
  proj_id  整形的数字,一般用ASCII码的单字符
  表示与参数1的运算。

返回值:成功 返回唯一键值
失败  -1;

 


ipcs -a 查询共享内存,信号量集,消息队列
ipcrm -s 删除信号量集
  -m 删除共享内存


共享内存 ===》效率最高的进程间通信方式



操作流程:
 key ==》申请对象 ==》映射对象==》读写对象
 ==》撤销映射 ==》删除对象



1、申请对象:

shmget()
#include <sys/ipc.h>
#include <sys/shm.h>
ps aux|grep a.out
share memory get  IPC_CREAT|0666
int shmget(key_t key, size_t size, int shmflg);


功能:使用唯一键值key向内核提出共享内存使用申请
参数:key  唯一键值
  size  要申请的共享内存大小
  shmflg 申请的共享内存访问权限,八进制表示
  如果是第一个申请,则用IPC_CREAT
  如果要检测是否存在,用IPC_EXCL
返回值:成功 返回共享内存id,一般用shmid表示
失败  -1;

share memory attach


2.映射对象:shmat()

void *shmat(int shmid, const void *shmaddr, int shmflg);


功能:将指定shmid对应的共享内存映射到本地内存。
参数:shmid 要映射的本地内存
  shmaddr 本地可用的地址,如果不确定则用NULL,表示
  由系统自动分配。
  shmflg  
  0,表示读写
  SHM_RDONLY,只读
返回值:成功 返回映射的地址,一般等于shmaddr
失败 (void*)-1
 


3.读写共享内存:类似堆区内存的直接读写:


char * p ;

write(fd,p,);
read(fd,p,1024);
memcpy(p,buf,1024);strcpy();
memset(p,0,1024);== bzero(p,1024);
memcmp(p,buf,1024); strcmp(a,b);



字符串:  strcpy(p,"hello");
字符/数字: 直接赋值

4.撤销映射:shmdt


int shmdt(const void *shmaddr);
功能:将本地内存与共享内存断开映射关系。
参数:shmaddr 要断开的映射地址。
返回值:成功  0
失败  -1;



5.删除对象:shmctl


int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:修改共享内存属性,也可以删除指定的共享内存对象。
参数:shmid 要删除的共享内存对象
  cmd IPC_RMID 删除对象的宏
  buff NULL 表示只删除对象。
返回值:成功 0
失败 -1
以上共享内存可能存在如下问题:
进程1 写入共享内存,如何通知进程2 读共享内存。



3.IPC对象之信号量集 ==>sem ===》为了解决共享内存的临界资源访问

 


操作流程:
key ==> 申请信号量集 ==》init==>PV操作 ===》删除信号量


semaphore


1、申请信号量  semget()


#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

int semget(key_t key, int nsems, int semflg);
功能:通过唯一键值向内核提出信号量申请。
参数:key 唯一键值
  nsems 要申请的信号量个数
  semflg 申请的信号量的访问权限
返回值:semid.
失败 -1;


2、pv操作;semop


p ==>sem_wait() ==>sem = sem-1;
v ==>sem_post() ==>sem = sem+1;

int semop(int semid, struct sembuf *sops, unsigned nsops);
功能:修改指定信号量集中信号量的值。
参数:semid 信号量集id
  sops ==》结构体如下:
  struct sembuf
  {
  unsigned short sem_num;  ///信号量集中信号量的编号,默认以0开始
  short  sem_op;   ///信号量的PV操作,如果改值等于-1则表示p
  等于1 则表示v
  等于0 则表示阻塞

  short   sem_flg;   ///信号量的操作方式 0 表示默认阻塞。
  IPC_NOWAIT and SEM_UNDO.
  };
  nsops 信号量的设置值个数。
返回值:成功 0
失败 -1

通常会将以上函数做如下自定义封装:

int my_sem_wait(int id,int sem)
{
struct sembuf mysem;
mysem.sem_num = sem;
mysem.sem_op  = -1;
mysem.flg   = 0;if(semop(id,&mysem,1) < 0)
return -1;
else
return 0;
}int my_sem_post(int id,int sem)
{
struct sembuf mysem;
mysem.sem_num = sem;
mysem.sem_op  = 1;
mysem.flg   = 0;if(semop(id,&mysem,1) < 0)
return -1;
else
return 0;
}


3、信号量的删除
 

int semctl(int semid, int semnum, int cmd, ...);
 功能:根据semid删除指定的信号量集
 参数:semid 要删除的信号量集
   semnum 要删除的信号量集中的信号量的编号
   cmd IPC_RMID 删除对象宏
   ...  可变长参数可以不写
返回值:成功 0
失败 -1;
 

这篇关于重头开始嵌入式第二十七天(Linux系统编程 信号通信)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Ubuntu系统怎么安装Warp? 新一代AI 终端神器安装使用方法

《Ubuntu系统怎么安装Warp?新一代AI终端神器安装使用方法》Warp是一款使用Rust开发的现代化AI终端工具,该怎么再Ubuntu系统中安装使用呢?下面我们就来看看详细教程... Warp Terminal 是一款使用 Rust 开发的现代化「AI 终端」工具。最初它只支持 MACOS,但在 20

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

Debian如何查看系统版本? 7种轻松查看Debian版本信息的实用方法

《Debian如何查看系统版本?7种轻松查看Debian版本信息的实用方法》Debian是一个广泛使用的Linux发行版,用户有时需要查看其版本信息以进行系统管理、故障排除或兼容性检查,在Debia... 作为最受欢迎的 linux 发行版之一,Debian 的版本信息在日常使用和系统维护中起着至关重要的作

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

LinuxMint怎么安装? Linux Mint22下载安装图文教程

《LinuxMint怎么安装?LinuxMint22下载安装图文教程》LinuxMint22发布以后,有很多新功能,很多朋友想要下载并安装,该怎么操作呢?下面我们就来看看详细安装指南... linux Mint 是一款基于 Ubuntu 的流行发行版,凭借其现代、精致、易于使用的特性,深受小伙伴们所喜爱。对