作者延续上一章的风格,demo级的介绍,帮助理解概念入门。
说实话,真没啥好解释的,中断就是程序跑着跑着,突然CPU接到了什么神谕,然后就对程序说“你站在此地不要动,我去买几个橘子”,直到cpu忙完了,程序才敢接着跑。
可以引入asm特性,像c一样嵌入汇编直接调软中断。
信号是操作系统特性,举的例子是SIGSTOP是暂停执行SIGCONT是继续执行。
可以用libc的signal、raise来自定义信号处理方式(libc::signal(信号名, 处理函数);)、发出信号。
本书最后一个例子加进了一个知识点——rust支持setjmp、longjmp这种操作:
#![feature(link_llvm_intrinsics)]
#![allow(non_camel_case_types)]
#![cfg(not(windows))]
use libc::{
SIGALRM, SIGHUP, SIGQUIT, SIGTERM, SIGUSR1,
};
use std::mem;
const JMP_BUF_WIDTH: usize =
mem::size_of::<usize>() * 8;
type jmp_buf = [i8; JMP_BUF_WIDTH];
static mut SHUT_DOWN: bool = false;
static mut RETURN_HERE: jmp_buf = [0; JMP_BUF_WIDTH];
const MOCK_SIGNAL_AT: usize = 3;
extern "C" {
#[link_name = "llvm.eh.sjlj.setjmp"]
pub fn setjmp(_: *mut i8) -> i32;
#[link_name = "llvm.eh.sjlj.longjmp"]
pub fn longjmp(_: *mut i8);
}
#[inline]
fn ptr_to_jmp_buf() -> *mut i8 {
unsafe { &RETURN_HERE as *const i8 as *mut i8 }
}
#[inline]
fn return_early() {
let franken_pointer = ptr_to_jmp_buf();
unsafe { longjmp(franken_pointer) };
}
fn register_signal_handler() {
unsafe {
libc::signal(SIGUSR1, handle_signals as usize);
}
}
#[allow(dead_code)]
fn handle_signals(sig: i32) {
register_signal_handler();
let should_shut_down = match sig {
SIGHUP => false,
SIGALRM => false,
SIGTERM => true,
SIGQUIT => true,
SIGUSR1 => true,
_ => false,
};
unsafe {
SHUT_DOWN = should_shut_down;
}
return_early();
}
fn print_depth(depth: usize) {
for _ in 0..depth {
print!("#");
}
println!();
}
fn dive(depth: usize, max_depth: usize) {
unsafe {
if SHUT_DOWN {
println!("!");
return;
}
}
print_depth(depth);
if depth >= max_depth {
return;
} else if depth == MOCK_SIGNAL_AT {
unsafe {
libc::raise(SIGUSR1);
}
} else {
dive(depth + 1, max_depth);
}
print_depth(depth);
}
fn main() {
const JUMP_SET: i32 = 0;
register_signal_handler();
let return_point = ptr_to_jmp_buf();
let rc = unsafe { setjmp(return_point) };
if rc == JUMP_SET {
dive(0, 10);
} else {
println!("early return!");
}
println!("finishing!")
}
就是这些。