win32-process(0.6.0) Process::kill 方法发送POSIX信号的问题

这两天在写一个工具,今天下午被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
本文版权归作者所有,只允许以摘要和完整全文两种形式转载,不允许对文字进行裁剪。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

要在Ubuntu上安装yaml-cpp0.6.0,你可以按照以下步骤进行操作: 1. 首先,你可以通过以下命令克隆yaml-cpp的源码库: ``` git clone https://github.com/jbeder/yaml-cpp.git ``` 2. 进入源码目录并创建一个build目录: ``` cd yaml-cpp && mkdir build && cd build ``` 3. 运行cmake命令来生成构建文件: ``` cmake -DYAML_BUILD_SHARED_LIBS=on .. ``` 4. 运行make命令来编译源码: ``` make ``` 5. 使用sudo权限运行make install命令来安装yaml-cpp: ``` sudo make install ``` 6. 最后,使用sudo ldconfig命令来更新共享库: ``` sudo ldconfig ``` 安装完成后,你可以在`/usr/local/include`目录下找到头文件,而库文件则位于`/usr/local/lib`目录下。这样,你就成功安装了yaml-cpp0.6.0版本。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [Ubuntu下yaml-cpp的安装](https://blog.csdn.net/taolusi/article/details/81074103)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ubuntu下yaml-cpp安装与使用](https://blog.csdn.net/qq_43278899/article/details/128474075)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值