day_12_信号处理、进程间通信
来源:互联网 发布:淘宝贷款条件是什么 编辑:程序博客网 时间:2024/05/29 04:44
- 一信号的处理
- 1 发送信号的系统函数
- 1raise
- sleep
- usleep
- pause
- 2alarm
- 1raise
- 2 信号集的基本概念和基本操作
- 1基本概念
- 2基本操作
- sigemptyset - 清空信号集
- sigfillset - 填满信号集
- sigaddset - 添加信号到信号集中
- sigdelset - 删除信号集中的信号
- sigismember - 判断信号是否存在
- 3 信号的屏蔽
- 1sigprocmask
- 2sigpending
- 4 计时器
- 5 扩展
- 1sigaction
- 2sigqueue
- 1 发送信号的系统函数
- 二进程间的通信技术
- 1 基本概念
- 2 通信方式
- 一信号的处理
一、信号的处理
1.1 发送信号的系统函数
(1)raise()
#include <signal.h>int raise(int sig);
- 功能:
- 主要用于给当前正在调用的线程/线程发送参数指定的信号,对于单线程的程序来说,等价于
kill(getpid(), sig);
- 返回值:
- success —- 0,error —- 非0;
sleep()
#include <unistd.h>unsigned int sleep(unsigned int seconds);
- 功能:
- 主要用于使得当前正在调用的线程进入睡眠状态,直到参数指定的秒数睡够了,或者一个不能被忽略的信号到达了;
- 返回值:
- 如果参数指定的秒数过去了,则返回0,否则返回还没有来得及睡的秒数,也就是剩余的秒数;
usleep()
#include <unistd.h>int usleep(useconds_t usec); //useconds = unsigned int;
- 功能:
- 主要用于使得当前正在调用的线程睡眠参数指定的微秒;
pause()
#include <unistd.h>int pause(void);
- 功能:
- 主要用于是的当前正在调用的进程或线程暂停程序的执行,等待信号的到来;
- 返回值:
- 只有当信号被捕获时返回-1,并设置errno为EINTR;
(2)alarm()
#include <unistd.h>unsigned int alarm(unsigned int seconds);
功能:
主要用于在进过参数指定的秒数之后,给当前正在调用的进程发送SIGALRM信号;
每次重新设置闹钟之后都会取消之前的闹钟,当参数为0时,专门用于取消闹钟;
返回值:
如果之前没有闹钟则返回0,否则返回之前闹钟剩余的秒数;
1.2 信号集的基本概念和基本操作
(1)基本概念
信号集本质上就是若干个信号组成的集合。
思考:
请问采用最节省内存空间的方式设计信号集的数据类型,如何设计?
分析:
int arr[64]; => 4*64 = 256B
short arr[64]; => 2*64 = 128B
char arr[64]; => 1*64 = 64B
采用每一个二进制位来代表一个信号,使用1表示有该信号,使用0表示没有该信号;=> 8B
… 0010 0011 => 存在信号1、信号2、信号6
结论:
操作系统内部使用数据类型:sigset_t
表示信号集的数据类型,该数据类型的大小是:128B;
typedef struct{ unsigned long int __val[(1024 / (8 * sizeof (unsigned long int)))];} __sigset_t; typedef __sigset_t sigset_t
(2)基本操作
sigemptyset() - 清空信号集
#include <signal.h>int sigemptyset(sigset_t *set);
sigfillset() - 填满信号集
#include <signal.h>int sigfillset(sigset_t *set);
sigaddset() - 添加信号到信号集中
#include <signal.h>int sigaddset(sigset_t *set, int signum);
sigdelset() - 删除信号集中的信号
#include <signal.h>int sigdelset(sigset_t *set, int signum);
sigismember() - 判断信号是否存在
#include <signal.h>int sigismember(const sigset_t *set, int signum);
返回值:
信号存在返回1,信号不存在返回0,出错返回-1;
1.3 信号的屏蔽
在某些特殊程序的执行过程中,可能不允许被信号打断,此时就需要使用信号的屏蔽技术来解决该问题;
(1)sigprocmask()
#include <signal.h>/* Prototype for the glibc wrapper function */int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
- 功能:
- 主要用于检查 / 修改即将屏蔽的信号集;
- 参数:
- 第一个参数:具体的屏蔽方式;
SIG_BLOCK - 使用当前屏蔽集 + 参数set屏蔽集
- ABC + CDE(set) =>ABCDE
SIG_UNBLOCK - 使用当前屏蔽集 - 参数set屏蔽集
- ABC - CDE(set) => AB
SIG_SETMASK - 使用参数set屏蔽集替换当前屏蔽集
- ABC CDE(set) => CDE
第二个参数:信号集类型的指针,用于指定新的信号集;
第三个参数:信号集类型的指针,用于带出之前屏蔽的信号集;
如果不想带出之前的屏蔽集,该参数给NULL即可;
注意:
信号的屏蔽并不是删除信号,而是相当于用一个隔板把信号档起来,对于可靠信号来说,产生了多少次,则在隔板的另一侧会排队等待多少个,而对于不可靠信号来说,无论产生了多少次,在隔板的另一侧只有一个信号排队等待,当信号的屏蔽解除时,相当于将隔板移开,只要进程不结束,则全部依次处理;
(2)sigpending()
#include <signal.h>int sigpending(sigset_t *set);
- 功能:
- 主要用于获取信号屏蔽期间来过但没来得及处理的信号集,通过参数set返回;
1.4 计时器
在linux系统中,操作系统会为每一个进程管理3种计时器,分别为:真实计时器、虚拟计时器以及实用计时器,一般都使用真实计时器进行计时;
#include <sys/time.h>int getitimer(int which, struct itimerval *curr_value);int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
- 功能:
- 主要用于获取 / 设置计时器的参数信息;
- 参数:
- 第一个参数:计时器的类型;
ITIMER_REAL - 真实计时器,产生SIGALRM信号
- 统计进程消耗的真实时间
ITIMER_VIRTUAL - 虚拟计时器,产生SIGVTALRM信号
- 统计进程在用户态下消耗的时间(了解)
ITIMER_PROF - 实用计时器,产生SIGPROF信号
- 统计进程在用户态和内核态消耗的总时间
第二个参数:结构体指针,用于指定计时器的新值;
struct itimerval{ struct timeval it_interval; /* 间隔时间 */ struct timeval it_value; /* 开始时间 */};struct timeval{ time_t tv_sec; /* 秒 */ suseconds_t tv_usec; /* 微秒 */};
第三个参数:结构体指针,用于带出设置之前的旧值;
1.5 扩展
(1)sigaction()
#include <signal.h>int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
- 功能:
- 主要用于设置信号的处理方式,signal()的增强版;
- 参数:
- 第一个参数:具体的信号值 / 信号名称;(SIGKILL和SIGSTOP除外)
第二个参数:结构体指针,设置指定信号新的处理方式;
struct sigaction{ void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void);};struct siginfo_t{ int si_signo; /* 信号值 */ ...}
第三个参数:结构体指针,获取指定信号原来的处理方式;
(2)sigqueue()
#include <signal.h>int sigqueue(pid_t pid, int sig, const union sigval value);
- 功能:
- 主要用于向指定的进程发送指定的信号,还可以带一个附加数据;
- 参数:
- 第一个参数:指定进程的进程号;
第二个参数:具体的信号值 / 信号名称,类似kill();
0 - - - - - 测试指定的进程是否存在
第三个参数:联合类型,
union sigval{ int sival_int; void *sival_ptr;};
… …
二、进程间的通信技术
2.1 基本概念
两个 / 多个进程之间的信息交互,就叫做进程间的通信;
2.2 通信方式
- 文件
- 信号
- 管道
- 共享内存
- 消息队列(重点)
- 信号量集
- 网络(重点)
… …
其中4、5、6通信方式统称为XSI IPC通信方式(X/open System Interface Inter-Process Communication)
练习:
尝试查询sigaction()的用法;
- 明日预报:
- (1)进程间的通信技术;
- day_12_信号处理、进程间通信
- 信号的处理(进程间通信)
- 进程间通信-信号
- 进程间通信--信号
- 进程间通信--信号
- 进程间通信-信号
- 进程间通信---信号
- 【进程间通信】信号
- 进程间通信----信号
- 【进程间通信】信号
- 信号通信(进程间通信)
- Linux进程间通信三之信号与处理
- 多进程间通信之信号中断处理
- Linux 进程间通信--信号、TCP粘包处理
- linux进程间通信、异步信号处理机制
- 【linux系统编程】进程间通信:信号中断处理
- Linux进程间的通信——信号处理
- linux进程间通信方式之信号处理sigaction
- Machine Learning:Regression with multi variables
- PAT:1005. 继续(3n+1)猜想 (25)
- hibernate设置默认值
- 【怎样写代码】偷窥高手 -- 反射技术(四):深入窥视属性
- easyui表格数据折叠的使用经验
- day_12_信号处理、进程间通信
- mongodb 查询条件
- 【JavaScript】一些基本的知识
- WUST 1873 潜水员 (二维背包) 【模板】
- 【ML--04】第四课 logistic回归
- 最大子序列和(java实现)
- RHEL7/Centos7系统root密码破解
- wx.navigateTo和wx.redirectTo无效
- Android开发之日期选择框详谈