C++中断和异常及它们的区别
中断(Interrupt)
中断是计算机系统中硬件或操作系统发出的信号,表示需要立即处理的事件。中断可以打断当前正在执行的代码,并将控制权交给一个中断服务程序(ISR)。中断主要用于处理实时事件,例如硬件输入/输出操作完成、定时器到期等。
中断的详细机制:
- 触发:中断通常由硬件设备触发。例如,键盘按键、网络数据到达等。
- 中断向量表:当中断发生时,系统会查找中断向量表,找到对应的ISR地址。
- 保存上下文:当前正在执行的任务被暂停,CPU保存其上下文(寄存器值、程序计数器等)。
- 执行ISR:CPU跳转到ISR开始执行。
- 恢复上下文:ISR执行完毕后,恢复之前保存的上下文,继续被中断的任务。
示例代码:
C++标准库中没有直接处理硬件中断的API,但我们可以使用信号(signals)来模拟类似行为。
#include <iostream>
#include <csignal>
#include <unistd.h>
// 中断服务程序(ISR)
void signalHandler(int signum)
{
std::cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭程序
exit(signum);
}
int main()
{
// 注册信号和信号处理函数
signal(SIGINT, signalHandler);
while(1)
{
std::cout << "Going to sleep..." << std::endl;
sleep(1);
}
return 0;
}
代码解释:
signal(SIGINT, signalHandler);
:注册SIGINT
信号(通常由 Ctrl+C 产生)的处理函数signalHandler
。while(1)
循环:程序进入无限循环,每秒钟输出一次 “Going to sleep…”。- 按下 Ctrl+C:产生
SIGINT
信号,中断当前执行,调用signalHandler
。 signalHandler
执行:输出中断信号编号,并退出程序。
异常(Exception)
异常是程序运行过程中检测到的错误条件,如非法操作、运行时错误等。C++使用 try
、catch
和 throw
关键字来处理异常。异常处理机制允许程序从错误状态中恢复,而不需要程序崩溃。
异常的详细机制:
- 抛出异常:当程序检测到错误时,可以使用
throw
关键字抛出异常。 - 捕获异常:异常被抛出后,程序会搜索匹配的
catch
块进行处理。如果找到匹配的catch
块,程序控制转移到该块,处理异常。 - 继续执行:异常处理完毕后,程序继续执行
catch
块后的代码。
示例代码:
#include <iostream>
#include <stdexcept>
// 可能抛出异常的函数
void mayThrow(int x)
{
if (x == 0)
{
throw std::invalid_argument("Received zero as argument");
}
else
{
std::cout << "Received: " << x << std::endl;
}
}
int main()
{
try
{
mayThrow(10); // 正常调用
mayThrow(0); // 抛出异常
}
catch (const std::invalid_argument& e)
{
std::cerr << "Caught exception: " << e.what() << std::endl;
}
std::cout << "Program continues..." << std::endl;
return 0;
}
代码解释:
mayThrow
函数:如果x
为 0,抛出std::invalid_argument
类型的异常,否则输出x
的值。try
块:包含可能抛出异常的代码。首先调用mayThrow(10)
正常执行,然后调用mayThrow(0)
抛出异常。catch
块:捕获std::invalid_argument
类型的异常,并输出异常信息。- 继续执行:捕获异常后,程序继续执行
catch
块后的代码,输出 “Program continues…”。
中断和异常的区别
本质区别:
- 中断:由外部事件(硬件或操作系统)触发,用于处理异步事件。
- 异常:由程序内部错误或特定条件触发,用于处理同步错误。
触发方式:
- 中断:硬件设备或操作系统事件(如定时器、I/O操作)。
- 异常:程序运行时的错误(如除零、数组越界、非法访问)。
处理方式:
- 中断:通过中断服务程序(ISR)处理,可能打断当前任务。
- 异常:通过
try
、catch
和throw
语句处理,通常不会立即打断当前任务,而是通过异常处理机制跳转到对应的catch
块。
适用场景:
- 中断:适用于需要及时响应的实时事件,如硬件中断、定时器中断。
- 异常:适用于需要在代码逻辑中处理的运行时错误,如输入验证错误、资源分配失败。
通过这些解释和示例代码,可以更清晰地理解中断和异常在C++中的具体应用和区别。