这两天在写一个工具,今天下午被win32-process(0.6.0)包的Process::kill方法浪费了2小时。
trap("INT") do
puts "got signal INT"
end
puts "Sup"
gets
Process.kill("INT", Process.pid);
这段代码举个例子,目的很简单,就是想接收和发送一个POSIX信号,验证执行上正确的结果。这个我本是准备用在fork子进程后,父向子通知消息用的,但是发现很简单的道理,可子进程就是不能进trap。后来发现问题是在于win32-process(0.6.0)包的Process::kill方法问。验证一下,上面的代码只要在首行加上:
require 'win32/process'
就立刻玩完,win32-process(0.6.0)包修改后的kill方法无法正确投递“SIGINT”中断。可怜的是,一方面为了在Windows平台上使用fork方法使用win32-process(0.6.0)包,而另一方面它的kill又有这个问题。不知道各位看客有什么高见,分享下。
另:今天休息,家里没*nix环境无法再实验了,等将来跨平台Review代码时再试吧。呵呵,看来Ruby还是和*nix亲。
// 11.30 18.10 添加 ////
刚google到一个,和我有同样的疑问,看来问题不是那么好解决。
http://stackoverflow.com/questions/140111/sending-an-arbitrary-signal-in-windows
// 11.30 18.11 添加 ////
看了一下win32-process(0.6.0)包process.rb的源代码,发现问题是在183行:
if GenerateConsoleCtrlEvent
(CTRL_C_EVENT, pid)
killed_pids.push(pid)
end
其中GenerateConsoleCtrlEvent函数始终失败,返回0值。通过kill方法上的注释和MSDN(http://msdn.microsoft.com/en-us/library/ms683155(VS.85).aspx
)里的说明看到,该函数成功处理CTRL_C_EVENT消息的必要条件是,必须要向进程标识中dwProcessGroupId
参数包含CREATE_NEW_PROCESS_GROUP(0x00000200)flag的进程发送消息才能够成功。为了验证,临时在process.rb中添加了个函数fork2:
def fork2
last_arg = ARGV.last
# Look for the 'child#xxx' tag
if last_arg =~ /child#\d+/
@i += 1
num = last_arg.split('#').last.to_i
if num == @i
if block_given?
status = 0
begin
yield
rescue Exception
status = -1 # Any non-zero result is failure
ensure
return status
end
end
return nil
else
return false
end
end
# Tag the command with the word 'child#xxx' to distinguish it
# from the calling process.
cmd = 'ruby -I "' + $LOAD_PATH.join(File::PATH_SEPARATOR) << '" "'
cmd << File.expand_path($PROGRAM_NAME) << '" ' << ARGV.join(' ')
cmd << ' child#' << @child_pids.length.to_s
startinfo = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
startinfo = startinfo.pack('LLLLLLLLLLLLSSLLLL')
procinfo = [0,0,0,0].pack('LLLL')
rv = CreateProcess(0, cmd, 0, 0, 1, CREATE_NEW_PROCESS_GROUP
, 0, 0, startinfo, procinfo)
if rv == 0
raise Error, get_last_error
end
pid = procinfo[8,4].unpack('L').first
@child_pids.push(pid)
pid
end
上面的代码就是复制的fork代码,只是其中红色代码行中的CreateProcess函数的第六个dwCreationFlags(DWORD)参数将CREATE_NEW_PROCESS_GROUP置位。之后执行测试代码:
require 'win32/process'
Signal.trap('INT') do
File.open("c:/c.txt", "w") { |f| f.write("ok") }
end
pid = Process::fork2
do
trap(2) { File.open("c:/b.txt", "w") { |f| f.write("ok") }; exit! }
while 1
sleep(2)
end
end
exit! if pid < 1
puts "Pause any key to send 'INT' sinal to child #{pid}"
gets
Process.kill(2, pid);
Process.kill('INT', Process.pid);
gets
puts "parent proc end."
发现对于fork2出的子进程GenerateConsoleCtrlEvent函数执行成功,即两个kill都执行成功。但是发现测试代码中的trap代码还是不能被执行。很是奇怪~
看了上面的google到的贴子,感觉可能是Windows没有很好的对POSIX信号支持造成的。再研究研究,大家有什么看法?期待中~~
// 2009.03.07 13:40 添加 ////
作者:lzy.je
出处:http://lzy.iteye.com
本文版权归作者所有,只允许以摘要和完整全文两种形式转载,不允许对文字进行裁剪。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
分享到:
相关推荐
"instantclient-basic-win32-11.1.0.6.0.zip"是Oracle公司为该平台提供的一个特定版本的下载包,它包含了运行Oracle数据库应用程序所需的最小集组件。 这个版本(11.1.0.6.0)可能稍显过时,但对一些仍在使用旧版...
yaml-cpp库的版本为0.6.0,其提供的功能强大且易于使用,是C++开发者处理YAML数据的理想选择。 在运维工作中,数据的管理与配置文件的读写至关重要。yaml-cpp库的引入,使得运维人员能够更加高效地处理这些YAML格式...
标题中的“1_ifcopenshell-python-37-v0.6.0-ed98983-win64_python读取ifc_Python”表明这是一个基于Python的IFC(Industry Foundation Classes)解析工具,名为ifcopenshell,适用于Python 3.7版本,且此版本号为v...
ByWave-Setup-0.6.0
cmpmvs-v0.6.0-binary-win64-cuda.zip https://www.dropbox.com/s/80savnaou9ck7v4/cmpmvs-v0.6.0-binary-win64-cuda.zip?dl=0 https://www.youtube.com/watch?v=ZRTEMKS3Sw0
clickhouse-jdbc-0.6.0.jar
赠送原API文档:tephra-api-0.6.0-javadoc.jar; 赠送源代码:tephra-api-0.6.0-sources.jar; 赠送Maven依赖信息文件:tephra-api-0.6.0.pom; 包含翻译后的API文档:tephra-api-0.6.0-javadoc-API文档-中文(简体)-...
赠送jar包:twill-discovery-api-0.6.0-incubating.jar; 赠送原API文档:twill-discovery-api-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-discovery-api-0.6.0-incubating-sources.jar; 赠送Maven依赖信息...
赠送jar包:twill-discovery-api-0.6.0-incubating.jar; 赠送原API文档:twill-discovery-api-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-discovery-api-0.6.0-incubating-sources.jar; 赠送Maven依赖信息...
赠送jar包:twill-zookeeper-0.6.0-incubating.jar; 赠送原API文档:twill-zookeeper-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-zookeeper-0.6.0-incubating-sources.jar; 赠送Maven依赖信息文件:twill-...
Kubernetes1.13 所需kubernetes-cni-0.6.0-0.x86_64.rpm rpm 包. tar -zxvf kubernetes-cni-0.6.0-0.x86_64.rpm.tar.gz yum install ./kubernetes-cni-0.6.0-0.x86_64.rpm kubelet-1.13.0 kubeadm-1.13.0 kubectl-...
赠送jar包:twill-api-0.6.0-incubating.jar; 赠送原API文档:twill-api-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-api-0.6.0-incubating-sources.jar; 赠送Maven依赖信息文件:twill-api-0.6.0-...
赠送jar包:twill-common-0.6.0-incubating.jar; 赠送原API文档:twill-common-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-common-0.6.0-incubating-sources.jar; 赠送Maven依赖信息文件:twill-common-...
赠送jar包:twill-core-0.6.0-incubating.jar; 赠送原API文档:twill-core-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-core-0.6.0-incubating-sources.jar; 赠送Maven依赖信息文件:twill-core-0.6.0-...
Tiled-Qt 0.6.0-win32正是这样一款专为游戏地图设计的软件,特别适用于Windows 32位操作系统。下面将详细介绍这个软件及其关键组成部分。 Tiled-Qt 0.6.0是一款基于Qt库构建的地图编辑器,它以其强大的功能和易用性...
赠送jar包:twill-zookeeper-0.6.0-incubating.jar; 赠送原API文档:twill-zookeeper-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-zookeeper-0.6.0-incubating-sources.jar; 赠送Maven依赖信息文件:twill-...
赠送jar包:twill-api-0.6.0-incubating.jar; 赠送原API文档:twill-api-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-api-0.6.0-incubating-sources.jar; 赠送Maven依赖信息文件:twill-api-0.6.0-...
赠送jar包:twill-common-0.6.0-incubating.jar; 赠送原API文档:twill-common-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-common-0.6.0-incubating-sources.jar; 赠送Maven依赖信息文件:twill-common-...
赠送jar包:twill-core-0.6.0-incubating.jar; 赠送原API文档:twill-core-0.6.0-incubating-javadoc.jar; 赠送源代码:twill-core-0.6.0-incubating-sources.jar; 赠送Maven依赖信息文件:twill-core-0.6.0-...
"jsoncpp-src-0.6.0-rc2"是JSONCPP的一个特定版本,代表着该库的源代码包,版本号为0.6.0的发布候选2(Release Candidate 2)。在软件开发中,发布候选版通常是在正式发布前的最后一个测试阶段,意味着它已经非常...