我正在尝试处理一些 *nix 信号并具有以下代码:
// nix = "0.8.0"
extern crate nix;
use nix::sys::signal::{SaFlags, SigAction, sigaction, SIGINT, SigSet};
use nix::sys::signal::SigHandler::Handler;
extern fn interrupted(_:i32) {
println!("Interrupted");
}
fn main() {
let sigact = SigAction::new(Handler(interrupted), SaFlags::empty(), SigSet::thread_get_mask().unwrap());
if let Err(_) = unsafe { sigaction(SIGINT, &sigact) } {
println!("Failed to register handler");
std::process::exit(1);
}
loop {
println!("Hello");
}
}
Run Code Online (Sandbox Code Playgroud)
我认为println!()
可以同时调用,但是当我中断时此代码总是出现恐慌
// nix = "0.8.0"
extern crate nix;
use nix::sys::signal::{SaFlags, SigAction, sigaction, SIGINT, SigSet};
use nix::sys::signal::SigHandler::Handler;
extern fn interrupted(_:i32) {
println!("Interrupted");
}
fn main() {
let sigact = SigAction::new(Handler(interrupted), SaFlags::empty(), SigSet::thread_get_mask().unwrap());
if let Err(_) = unsafe { sigaction(SIGINT, &sigact) } {
println!("Failed to register handler");
std::process::exit(1);
}
loop {
println!("Hello");
}
}
Run Code Online (Sandbox Code Playgroud)
的文档println!()
没有具体提到并发执行的任何恐慌,只是说它在无法写入标准输出时会出现恐慌。我对这种恐慌有点困惑,因为println!()
从循环中的多个线程调用工作正常。
问题是println!()
线程安全的,但在同一线程上不安全,即,当println!()
in的第一个实例被中断并且在同一线程上调用main
第二个实例时,会违反一些线程局部静态依赖关系,或者如何interrupted
我想象的是这个?
问题是
println!()
线程安全的,但在同一线程上不安全,即,当println!()
in的第一个实例被中断并且在同一线程上调用main
第二个实例时,会违反一些线程本地静态依赖关系[...interrupted
]?
是的,差不多是这样。
该println!()
宏委托给print!()
,后者调用std::io::_print
,后者print_to
通过&LOCAL_STDOUT
作为参数传递来调用。LOCAL_STDOUT
定义如下:
/// Stdout used by print! and println! macros
thread_local! {
static LOCAL_STDOUT: RefCell<Option<Box<Write + Send>>> = {
RefCell::new(None)
}
}
Run Code Online (Sandbox Code Playgroud)
您看到的恐慌RefCell
来自LOCAL_STDOUT
. 信号处理程序在接收信号的线程上运行。因此,当发出信号时,信号处理程序可以在RefCell
可变借用的同时运行。由于RefCell
一次只允许一个可变借用,因此尝试println!()
在信号处理程序中使用可能会出现恐慌。
归档时间: |
|
查看次数: |
996 次 |
最近记录: |