You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows批处理接收Ctrl+C时向Python子进程发送SIGINT的方案问询

问题根源

你当前使用START /B启动的Python进程属于独立的后台进程,和运行批处理的主控制台进程不在同一个进程组,按下Ctrl+C时系统仅会将SIGINT信号发送给批处理主进程,不会同步转发给后台的Python子进程,因此你写的信号处理逻辑无法被触发。


解决方案1:修改原有批处理脚本

修改后的批处理会记录两个Python进程的PID,捕获Ctrl+C事件后调用系统接口向子进程发送CTRL_C_EVENT信号,触发你预设的信号处理逻辑:

@echo off
setlocal enabledelayedexpansion

:: 启动GNSS采集脚本并记录进程ID
start "" /B "C:\Users\nisso\anaconda3\envs\sensor_logging\python.exe" "C:/Users/nisso/Desktop/sensor_logging/gnss_reader.py"
set GNSS_PID=%!

:: 启动IMU采集脚本并记录进程ID
start "" /B "C:\Users\nisso\anaconda3\envs\sensor_logging\python.exe" "C:/Users/nisso/Desktop/sensor_logging/imu_reader.py"
set IMU_PID=%!

echo 采集程序已启动,GNSS PID: %GNSS_PID%, IMU PID: %IMU_PID%
echo 按下Ctrl+C停止采集

:: 注册Ctrl+C退出处理逻辑
if not "%1"=="" goto on_exit

:: 后台等待中断信号
:loop
timeout /t 1 /nobreak >nul
goto loop

:on_exit
echo 正在停止采集程序,请稍候...
:: 调用PowerShell向子进程发送CTRL_C_EVENT信号
powershell -Command "$sig = Add-Type 'using System;using System.Runtime.InteropServices;public class Sig {[DllImport(\"kernel32.dll\")]public static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);[DllImport(\"kernel32.dll\")]public static extern bool AttachConsole(uint dwProcessId);[DllImport(\"kernel32.dll\")]public static extern bool FreeConsole();}' -PassThru; $sig::FreeConsole(); if ($sig::AttachConsole(%GNSS_PID%)) { $sig::GenerateConsoleCtrlEvent(0, 0); Start-Sleep -Milliseconds 500; $sig::FreeConsole(); }; if ($sig::AttachConsole(%IMU_PID%)) { $sig::GenerateConsoleCtrlEvent(0, 0); Start-Sleep -Milliseconds 500; $sig::FreeConsole(); }"
:: 等待进程完成残留写入后退出
timeout /t 2 /nobreak >nul
echo 采集已安全停止
exit /b 0

解决方案2:使用PowerShell启动(更简洁)

如果可以接受用PowerShell脚本替代批处理,逻辑更简单稳定,保存为start_collect.ps1运行即可:

# 启动两个采集进程并获取PID
$gnssProc = Start-Process -FilePath "C:\Users\nisso\anaconda3\envs\sensor_logging\python.exe" -ArgumentList "C:/Users/nisso/Desktop/sensor_logging/gnss_reader.py" -NoNewWindow -PassThru
$imuProc = Start-Process -FilePath "C:\Users\nisso\anaconda3\envs\sensor_logging\python.exe" -ArgumentList "C:/Users/nisso/Desktop/sensor_logging/imu_reader.py" -NoNewWindow -PassThru

try {
    # 等待进程运行,捕获Ctrl+C中断
    Wait-Process -Id $gnssProc.Id, $imuProc.Id -ErrorAction Stop
}
catch {
    Write-Host "正在停止采集程序,请稍候..."
    # 发送CTRL_C_EVENT信号
    $sig = Add-Type 'using System;using System.Runtime.InteropServices;public class Sig {[DllImport("kernel32.dll")]public static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);[DllImport("kernel32.dll")]public static extern bool AttachConsole(uint dwProcessId);[DllImport("kernel32.dll")]public static extern bool FreeConsole();}' -PassThru
    $sig::FreeConsole()
    if ($sig::AttachConsole($gnssProc.Id)) {
        $sig::GenerateConsoleCtrlEvent(0, 0)
        Start-Sleep -Milliseconds 500
        $sig::FreeConsole()
    }
    if ($sig::AttachConsole($imuProc.Id)) {
        $sig::GenerateConsoleCtrlEvent(0, 0)
        Start-Sleep -Milliseconds 500
        $sig::FreeConsole()
    }
    # 等待进程完成写入后退出
    Wait-Process -Id $gnssProc.Id, $imuProc.Id -Timeout 2
    Write-Host "采集已安全停止"
}

可选优化

建议在你的Python代码的写入逻辑后添加手动刷新缓存的代码,避免缓存中的数据未写入磁盘:

f.write(f"{t}\t{serialString}\n")
f.flush()

内容的提问来源于stack exchange,提问作者Morten Nissov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 19:15:00