在两个线程中加载Expect后,puts无法输出到stdout的问题求助
问题:多线程加载Expect后stdout输出异常
环境信息
- 系统:Windows 10
- Tcl版本:8.6
- Thread包版本:2.6.6
- Expect包版本:5.43.2
问题现象
在两个子线程中分别调用package require Expect后,仅第一个线程的puts能输出到控制台,第二个线程的输出丢失。相关测试代码及运行结果如下:
测试代码
package require Thread #package require Expect thread::create { package require Expect exp_log_user 1 puts "hello" } thread::create { package require Expect exp_log_user 1 puts "hello2" } after 2000
运行输出
C:\thread>tclsh samp2.tcl hello C:\thread>
解决方案
方案1:主线程提前加载Expect包
将package require Expect移至主线程执行,子线程共享已加载的包上下文,避免多次加载导致的stdout冲突。修改后代码:
package require Thread package require Expect thread::create { exp_log_user 1 puts "hello" } thread::create { exp_log_user 1 puts "hello2" } after 2000
方案2:子线程加载Expect后重置stdout
若必须在子线程中加载Expect,可在加载后手动重新打开stdout,恢复控制台输出通道:
package require Thread thread::create { package require Expect exp_log_user 1 # 重新绑定stdout到控制台 set stdout [open "stdout" w] puts "hello" } thread::create { package require Expect exp_log_user 1 # 重新绑定stdout到控制台 set stdout [open "stdout" w] puts "hello2" } after 2000
方案3:通过主线程统一处理输出
利用Tcl线程的消息传递机制,子线程将输出内容发送至主线程,由主线程负责打印,彻底避免子线程直接操作stdout的冲突:
package require Thread thread::create { package require Expect exp_log_user 1 # 向主线程发送输出指令 thread::send [thread::main] {puts "hello"} } thread::create { package require Expect exp_log_user 1 # 向主线程发送输出指令 thread::send [thread::main] {puts "hello2"} } after 2000
内容的提问来源于stack exchange,提问作者Active Hub
相关产品推荐
相关产品推荐

