Servo ipc-channel最简示例运行失败求助
使用servo/ipc-channel实现IPC时子进程连接失败(错误码1102)
问题概述
尝试用servo的ipc-channel库实现进程间通信,最简示例无法正常运行。主进程创建IpcOneShotServer后启动子进程,子进程通过bash脚本启动另一个Crate,尝试连接IPC通道时触发Unknown(1102)错误,程序panic。
相关代码
主进程(process_handler项目)
use std::process::Command; use ipc_channel::ipc::{self, IpcOneShotServer, IpcSender, IpcReceiver}; fn main() { let datavec = vec![("Peter".to_string(), "36".to_string())]; // 注:原代码未展示server_name0的创建逻辑,推测为IpcOneShotServer::new()生成的名称 let guiserver = spawn_server( "/Users/peterweyand/Code/rustprojects/project1.1/project1_1/process_handler/src/rungui.sh".to_string(), &server_name0 ); } pub fn spawn_server(address: String, test_name: &str) -> std::process::Child { Command::new(address) .arg(test_name) .spawn() .expect("failed to execute server process") }
启动子进程的bash脚本(rungui.sh)
#!/bin/bash echo "inside rungui.sh" echo "First Parameter of the script is $1" cd /Users/peterweyand/Code/rustprojects/project1.1/project1_1 cargo build && cargo run -- $1
子进程Crate代码
use iced::widget::{button, container, row, column, text, text_input}; use iced::{executor, Application, Command, Length, Settings}; use ipc_channel::ipc::{self, IpcOneShotServer, IpcSender, IpcReceiver}; use iced::Color; use self::theme::Theme; use self::widget::Element; use std::collections::HashMap; use std::process::Command as ProcessCommand; use std::env; use std::io; use std::{thread, time}; fn main() { let args: Vec<String> = env::args().collect(); println!("&cloned_string: {:?}", args[1].clone()); let tx2 = IpcSender::<Vec<(String, String)>>::connect(args[1].clone()).unwrap(); }
错误信息
&cloned_string: "org.rust-lang.ipc-channel.8687042407079962014" thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: Unknown(1102) }', src/main.rs:59:76
问题原因及解决方法
核心原因
错误码1102对应macOS系统错误EOPNOTSUPP(Operation not supported),最可能的触发场景是主进程的IpcOneShotServer在子进程完成连接前就被销毁:主进程创建server后未等待子进程连接,直接执行完毕退出,导致IPC通道被回收,子进程尝试连接时通道已不存在。
解决步骤
保持主进程的
IpcOneShotServer存活
修改主进程代码,确保在子进程完成连接并通信前,server对象不被drop:use std::process::Command; use ipc_channel::ipc::{self, IpcOneShotServer, IpcSender, IpcReceiver}; fn main() { let datavec = vec![("Peter".to_string(), "36".to_string())]; // 显式创建IpcOneShotServer并持有其实例 let (server, server_name0) = IpcOneShotServer::new().unwrap(); let guiserver = spawn_server( "/Users/peterweyand/Code/rustprojects/project1.1/project1_1/process_handler/src/rungui.sh".to_string(), &server_name0 ); // 等待子进程连接,保持server存活 let (tx, rx): (IpcSender<Vec<(String, String)>>, IpcReceiver<()>) = server.accept().unwrap(); // 发送数据到子进程(如果需要) tx.send(datavec).unwrap(); // 等待子进程执行完毕后再退出主进程 let _ = guiserver.wait(); } pub fn spawn_server(address: String, test_name: &str) -> std::process::Child { Command::new(address) .arg(test_name) .spawn() .expect("failed to execute server process") }验证IPC通道名称传递正确性
确保bash脚本和子进程正确接收并使用主进程传递的server名称,避免字符串截断或编码问题。排查权限隔离
确认主进程和子进程运行在相同用户权限下,无沙盒或容器隔离导致的IPC通道访问限制。
内容的提问来源于stack exchange,提问作者yosemeti
相关产品推荐
相关产品推荐

