当前位置: 首页 > wzjs >正文

阿里巴巴logo的含义搜索引擎优化的步骤

阿里巴巴logo的含义,搜索引擎优化的步骤,网站外链怎么做,建网站用的免费软件进程信号 信号生成函数kill 函数raise 函数abort 函数 软件条件产生的信号SIGPIPE信号alarm函数与SIGALRM信号alarm函数SIGALRM信号实验对比:IO效率对程序性能的影响设置重复闹钟的实现 软件条件的深入理解扩展知识:更精确的定时器 硬件异常产生信号硬件…

进程信号

  • 信号生成函数
    • kill 函数
    • raise 函数
    • abort 函数
  • 软件条件产生的信号
    • SIGPIPE信号
    • alarm函数与SIGALRM信号
      • alarm函数
      • SIGALRM信号
      • 实验对比:IO效率对程序性能的影响
      • 设置重复闹钟的实现
    • 软件条件的深入理解
    • 扩展知识:更精确的定时器
  • 硬件异常产生信号
    • 硬件异常信号概述
    • 典型硬件异常信号分析
    • Core Dump机制
    • 硬件异常处理流程
    • 关键问题思考
      • 信号集的基本概念(补充)
    • 扩展知识:CPU异常处理机制
    • 常见问题解答

信号生成函数

kill 函数

1.基本功能

用于向指定进程发送指定信号。是Linux系统中kill命令的实现基础。

2.函数原型

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

3.参数说明
pid:目标进程ID

  • pid > 0:发送给指定PID的进程

  • pid = 0:发送给与调用进程同组的所有进程

  • pid = -1:发送给所有有权限发送的进程(除init进程外)

  • pid < -1:发送给进程组ID等于pid绝对值的所有进程

sig:要发送的信号编号(如SIGTERM=15,SIGKILL=9)

4.返回值
成功:返回0

失败:返回-1,并设置errno

5.示例代码

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>int main(int argc, char *argv[]) {if(argc != 3) {std::cerr << "Usage: " << argv[0] << " -signumber pid" << std::endl;return 1;}int signum = std::stoi(argv[1]+1); // 跳过'-'字符pid_t pid = std::stoi(argv[2]);return kill(pid, signum);
}

6.补充说明
权限要求:发送进程必须有权限向目标进程发送信号

特殊信号:发送信号0(空信号)可用于检查目标进程是否存在

常用信号

  • SIGTERM(15):温和终止信号,可被捕获和处理

  • SIGKILL(9):强制终止信号,不可被捕获或忽略

  • SIGINT(2):终端中断信号(通常由Ctrl+C产生)

raise 函数

1.基本功能

向当前进程(自己)发送指定信号,相当于kill(getpid(), sig)。

2.函数原型

#include <signal.h>int raise(int sig);

3.参数说明
sig:要发送的信号编号

4.返回值
成功:返回0

失败:返回非零值

5.示例代码

#include <iostream>
#include <unistd.h>
#include <signal.h>void handler(int signum) {std::cout << "Received signal: " << signum << std::endl;
}int main() {signal(SIGINT, handler); // 设置SIGINT(2)的信号处理函数while(true) {sleep(1);raise(SIGINT); // 每隔1秒向自己发送SIGINT信号}
}

6.补充说明
线程安全:在多线程环境中,raise()会向调用线程而不是整个进程发送信号

用途:常用于触发信号处理程序或测试信号处理逻辑

abort 函数

1.基本功能
使当前进程异常终止,发送SIGABRT信号(6号信号)给自己。

默认行为是终止进程并生成核心转储文件

2.函数原型

#include <stdlib.h>void abort(void);

3.返回值

无返回值(函数不会返回)

4.示例代码

#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>void handler(int signum) {std::cout << "Received signal: " << signum << std::endl;// 即使捕获了SIGABRT,进程仍会终止
}int main() {signal(SIGABRT, handler);sleep(1);abort(); // 发送SIGABRT信号std::cout << "This line will never be executed" << std::endl;return 0;
}

5.补充说明
不可阻挡:即使捕获或忽略了SIGABRT信号,abort()仍会终止进程。

清理工作:abort()不会调用atexit()注册的函数。

与exit的区别

exit()是正常终止,会执行清理工作。

abort()是异常终止,可能生成核心转储。

用途:通常在检测到严重错误(如断言失败)时调用。

软件条件产生的信号

SIGPIPE信号

1.产生条件
当进程向一个已经关闭读端的管道或socket写入数据时产生。

是一种由软件条件触发的信号。

2.默认行为
终止进程。

3.处理建议
通常应该捕获并处理SIGPIPE信号。

或者在写操作前检查管道/套接字状态。

alarm函数与SIGALRM信号

alarm函数

1.功能
设置一个定时器(闹钟),在指定秒数后向进程发送SIGALRM信号

2.函数原型

#include <unistd.h>
unsigned int alarm(unsigned int seconds);

3.参数
seconds:定时时间(秒)

0表示取消之前设置的闹钟

4.返回值
之前设置的闹钟剩余时间(秒)

如果没有之前设置的闹钟则返回0

5.特点
每个进程只能有一个活跃的alarm定时器

新的alarm调用会覆盖之前的设置

SIGALRM信号

1.默认行为
终止进程

2.常见用途
实现超时机制。

周期性任务调度。

性能测试(如计算CPU运算速度)。

实验对比:IO效率对程序性能的影响

高IO版本(效率低)

#include <iostream>
#include <unistd.h>int main() {int count = 0;alarm(1);while(true) {std::cout << "count: " << count << std::endl;count++;}return 0;
}

结果:1秒内只能计数到约10万次

低IO版本(效率高)

#include <iostream>
#include <unistd.h>
#include <signal.h>int count = 0;void handler(int) {std::cout << "count: " << count << std::endl;exit(0);
}int main() {signal(SIGALRM, handler);alarm(1);while(true) count++;return 0;
}

结果:1秒内能计数到约5亿次

结论
IO操作(如打印输出)会显著降低程序执行速度.

减少IO可以大幅提高CPU密集型任务的性能.

设置重复闹钟的实现

1.实现方法

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <vector>
#include <functional>using func_t = std::function<void()>;
std::vector<func_t> gfuncs;void handler(int) {for(auto &f : gfuncs) f();alarm(1); // 重新设置闹钟
}int main() {// 添加周期性任务gfuncs.push_back([](){ /* 任务1 */ });gfuncs.push_back([](){ /* 任务2 */ });signal(SIGALRM, handler);alarm(1); // 初始设置while(true) {pause(); // 等待信号}
}

2.关键点
在信号处理函数中重新设置alarm。

使用pause()挂起进程等待信号。

可以注册多个周期性任务。

软件条件的深入理解

1.定义
软件条件是指由程序内部状态特定软件操作触发的信号产生机制,区别于硬件产生的信号(如SIGSEGV)。

2.常见软件条件信号
SIGALRM:由alarm/setitimer等定时器函数触发

SIGPIPE:向断开连接的管道/套接字写入数据

SIGURG:套接字上出现紧急数据

SIGCHLD:子进程状态改变

3.操作系统实现原理
定时器管理:

内核维护定时器数据结构(如timer_list)

使用时间轮或堆结构高效管理大量定时器

定时器超时后触发中断处理程序

信号传递:

内核检查目标进程的信号屏蔽字(信号是可以设置屏蔽的)

将信号加入待处理信号集

在适当时机(如系统调用返回前)递送信号

扩展知识:更精确的定时器

1.setitimer函数

#include <sys/time.h>
int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);

提供更精确的定时控制(微秒级)

支持三种定时器类型

  • ITIMER_REAL:真实时间,产生SIGALRM

  • ITIMER_VIRTUAL:进程虚拟时间,产生SIGVTALRM

  • ITIMER_PROF:进程虚拟时间+系统时间,产生SIGPROF

2.现代替代方案
timer_create:POSIX定时器API

epoll/select:可用于实现高精度定时

timerfd:Linux特有的定时器文件描述符

3. 实际应用场景

实现超时机制

void operation_with_timeout(int seconds) {signal(SIGALRM, [](int){ /* 超时处理 */ });alarm(seconds);// 执行可能阻塞的操作alarm(0); // 取消超时
}

周期性任务调度

void schedule_periodic_task(int interval) {signal(SIGALRM, [](int){ /* 执行任务 */alarm(interval); // 重新调度});alarm(interval);
}

性能基准测试

void benchmark() {volatile int count = 0;signal(SIGALRM, [](int){ std::cout << "Operations per second: " << count << std::endl;exit(0);});alarm(1);while(true) count++;
}

4. 注意事项

信号安全性

信号处理函数应只使用异步信号安全函数

避免在信号处理函数中进行复杂操作

竞态条件

alarm返回值和实际信号递送之间可能存在竞争

考虑使用sigprocmask进行信号屏蔽

多线程环境

在多线程程序中,信号处理变得更加复杂

建议使用专门的信号处理线程

可移植性

alarm的精度有限(秒级)

考虑使用POSIX定时器API提高可移植性

硬件异常产生信号

硬件异常信号概述

1.产生机制
硬件检测到异常(如除零、非法内存访问)后通知内核

内核将硬件异常转换为相应信号发送给进程

2.常见硬件异常信号

信号编号触发条件默认动作
SIGFPE8算术异常(如除零、溢出)Core
SIGSEGV11无效内存引用(段错误)Core
SIGILL4非法指令Core
SIGBUS7总线错误(内存对齐错误等)Core
SIGTRAP5断点/陷阱指令Core

典型硬件异常信号分析

1.SIGFPE(浮点异常)

模拟除零异常

#include <stdio.h>
#include <signal.h>void handler(int sig) {printf("Caught signal: %d\n", sig);// 注意:不退出会导致无限循环接收信号
}int main() {signal(SIGFPE, handler);  // 注册信号处理函数sleep(1);int a = 10;a /= 0;  // 触发除零异常while(1);  // 保持进程不退出return 0;
}

关键现象
会不断收到SIGFPE信号

原因:CPU状态寄存器未被清除,异常状态持续存在

2.SIGSEGV(段错误)
模拟野指针访问

#include <stdio.h>
#include <signal.h>void handler(int sig) {printf("Caught signal: %d\n", sig);
}int main() {signal(SIGSEGV, handler);  // 注册信号处理函数sleep(1);int *p = NULL;*p = 100;  // 触发段错误while(1);  // 保持进程不退出return 0;
}

关键现象
会不断收到SIGSEGV信号

原因:非法内存访问状态未被修复

Core Dump机制

1.基本概念
进程异常终止时将用户空间内存数据保存到core文件

用于事后调试(Post-mortem Debug)
在这里插入图片描述

2.配置方法

# 查看当前core文件限制
ulimit -a# 设置core文件大小限制(单位:KB)
ulimit -c 1024# 取消限制(允许生成任意大小的core文件)
ulimit -c unlimited

在这里插入图片描述
在这里插入图片描述

3.产生Core Dump的信号

  • SIGQUIT(Ctrl+\)

  • SIGABRT

  • SIGFPE

  • SIGSEGV

  • SIGILL

  • SIGBUS

4.示例:获取子进程退出状态

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>int main() {if (fork() == 0) {  // 子进程sleep(1);int a = 10;a /= 0;  // 触发除零异常exit(0);}int status = 0;waitpid(-1, &status, 0);printf("Exit signal: %d, core dump: %d\n", status & 0x7F, (status >> 7) & 1);return 0;
}

硬件异常处理流程

1.异常发生:

CPU执行指令时检测到异常

2.硬件响应:

保存当前上下文

跳转到内核异常处理程序

3.内核处理:

分析异常类型

转换为相应信号

检查进程的信号处理方式

4.信号递送:

如果捕获了信号,调用用户注册的处理函数

否则执行默认动作(终止+可能core dump)

关键问题思考

1.为什么必须由OS处理信号?
OS是进程的管理者,具有最高权限

只有OS能访问硬件和CPU状态寄存器

保证系统安全和稳定性

2.信号是否立即处理?
不是立即处理,而是在从内核态返回用户态时处理

内核会在以下时机检查并处理待处理信号:

  • 系统调用返回时

  • 中断处理完成时

  • 进程从睡眠状态被唤醒时

3.信号如何暂存?
内核为每个进程维护两个信号集:

  • pending:已产生但未递送的信号

  • blocked:被阻塞的信号

使用位图结构高效存储

信号集的基本概念(补充)

1. 信号集定义
信号集(sigset_t)是一个位掩码数据结构,用于表示一组信号的集合。每个信号对应一个位,位值为1表示信号在集合中,0表示不在集合中。

2. 信号集的数据类型
在Linux中,信号集通常定义为:

typedef struct {unsigned long sig[_NSIG_WORDS];
} sigset_t;

3. 信号集的作用
表示被阻塞的信号集合

表示等待处理的信号集合

表示信号处理函数的信号掩码


4.进程如何知道信号处理方式?

a.每个进程的PCB中保存信号处理表
包含每个信号的处理方式:

  • 忽略

  • 默认

  • 自定义处理函数

b.完整的信号处理流程
信号产生

硬件异常/软件条件/其他进程发送

信号记录

内核将信号加入目标进程的pending集合

信号递送

在合适时机检查pending信号

对于未阻塞的信号

执行默认动作,或调用用户注册的处理函数

处理完成

从信号处理函数返回后恢复原执行流程

扩展知识:CPU异常处理机制

1.CPU异常分类

故障(Fault)

可修复的异常(如页故障)

修复后重新执行指令

陷阱(Trap)

指令执行后触发(如断点)

用于调试和系统调用

中止(Abort)

严重错误(如硬件故障)

通常导致进程终止

2.关键寄存器
CR0-CR4:控制寄存器

EFLAGS:状态标志寄存器

TF(Trap Flag):单步调试

IF(Interrupt Flag):中断使能

IDTR:中断描述符表寄存器

常见问题解答

1.为什么有些信号会不断重复触发?

因为异常状态未被清除

解决方案:

在信号处理函数中修复异常状态,或直接终止进程

2.如何区分不同类型的SIGSEGV?
通过si_addr(访问地址)和si_code(错误代码):

复制
void handler(int sig, siginfo_t *info, void *ucontext) {printf("Fault address: %p\n", info->si_addr);printf("Reason: %d\n", info->si_code);
}

3.为什么有时看不到core文件?

可能原因:

  • ulimit限制

  • 文件系统权限

  • 存储空间不足

  • 进程工作目录不可写

http://www.dtcms.com/wzjs/67547.html

相关文章:

  • 网站的按钮怎么做 视频kol营销
  • 企业微信网站开发建网站流程
  • 公司想推广做网站有用百度竞价价格查询
  • 做网站还需要续费天津seo排名效果好
  • 如何做天猫网站百度关键词seo公司
  • 广州信科做网站官网seo是什么
  • 企业宣传网站建设图示网络营销招聘
  • 有没有帮忙做推广的网站百度安装
  • 平度推广网站建设网站建设详细方案模板
  • 自己做的网站打不开了免费的网站域名查询app
  • crm网站推荐网站优化推广哪家好
  • 宝安高端网站设计怎么样能让手机流畅到爆的软件
  • 网站建设一站式seo内链优化
  • 怎么做网站像淘宝这样的营销渠道
  • 网站建设方案书要怎么样写跨境电商培训
  • 网站图片上传代码天津百度关键词seo
  • 上海专业建站最低价企查查在线查询
  • 佛山公司官网制作哪家好宁波seo网络推广咨询价格
  • 强的小企业网站建设seo标题生成器
  • 潍坊市做网站营销模式
  • 美女教师做爰网站现在推广引流什么平台比较火
  • 博彩类网站怎么做跨境电商哪个平台比较好
  • 网站文章怎么做标签快速排名提升
  • 做网站常见程序网络推广公司企业
  • 网站建设日程安排seo属于运营还是技术
  • 电子商务网站建设实训室简介网络营销推广
  • 如何将网站做成app东莞推广服务
  • 东莞浩智网站建设多少钱江门seo网站推广
  • h5免费制作平台无水印seo优化范畴
  • 洞泾做网站网络广告有哪些形式