叉,红宝石,ActiveRecord的和文件上叉描述符 [英] Fork, Ruby, ActiveRecord and File Descriptors on Fork

查看:139
本文介绍了叉,红宝石,ActiveRecord的和文件上叉描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,当我们创建一个进程的子进程继承了父母打开的文件描述符和偏移的副本。据该名男子页这是指所用的亲本相同的文件描述符。根据这一理论,在下面的程序

I understand that when we fork a process the child process inherits a copy of the parents open file descriptors and offsets. According to the man pages this refers to the same file descriptors used by the parent. Based on that theory in the following program



puts "Process #{Process.pid}"

file = File.open('sample', 'w')

forked_pid = fork do
    sleep(10)
    puts "Writing to file now..."
    file.puts("Hello World. #{Time.now}")       
end




file.puts("Welcome to winter of my discontent #{Time.now}")
file.close
file = nil

问题1: 不应该是睡觉10秒的分叉过程中失去它的文件描述符,并不能写入文件的父进程完成并关闭该文件并退出。
问题2:但不管出于什么原因,如果这个工程再如何的ActiveRecord失去其在这种情况下连接。它只能如果我设置:重新连接=>真正的的ActiveRecord的连接可以在实际连接,这意味着它的失败连接。

Question 1: Shouldn't the forked process which is sleeping for 10 seconds lose its file descriptor and not be able to write to the file as the parent process completes and closes the file and exits.
Question 2: But for whatever reason if this works then how does ActiveRecord lose its connection in this scenario. It only works if I set :reconnect => true on ActiveRecord connect can it actually connect, which means its losing connection.



require "rubygems"
require "redis"
require 'active_record'
require 'mysql2'

connection = ActiveRecord::Base.establish_connection({
    :adapter => 'mysql2',
    :username => 'root_user',
    :password => 'Pi',
    :host => 'localhost',
    :database => 'list_development', 
    :socket => '/var/lib/mysql/mysql.sock'

    })

class User < ActiveRecord::Base   
end

u = User.first

puts u.inspect

fork do
    sleep 3
    puts "*" * 50
    puts User.first.inspect
    puts "*" * 50

end

puts User.first.inspect

然而,同样是不符合Redis的(v2.4.8),真的,不输在叉子上连接了。是否它试图在叉子内部重新连接?

However, the same is not true with Redis (v2.4.8) which does not lose connection on a fork, again. Does the it try to reconnect internally on a fork?

如果多数民众赞成的情况下,为什么不写文件的程序不是抛出一个错误。

If thats the case then why isn't the write file program not throwing an error.

有人能解释一下什么怎么回事。谢谢

Could somebody explain whats going on here. Thanks

推荐答案

如果你在一个进程关闭文件描述符它停留在其他进程有效,这就是为什么你的文件,例如工作正常。

If you close a file descriptor in one process it stays valid in the other process, this is why your file example works fine.

MySQL的情况不同,因为它是与另一个进程在最后一个插座。当你调用close MySQL适配器(或适配器时变垃圾回收时,红宝石退出)实际发送一个退出命令,服务器说,你是断开,所以服务器眼泪插槽的一面朝下。一般来说,你真的不希望共享两个进程之间的MySQL连接 - 你会得到奇怪的错误取决于两个进程是否正在尝试使用套接字在同一时间

The mysql case is different because it's a socket with another process at the end. When you call close on the mysql adapter (or when the adapter gets garbage collected when ruby exits) it actually sends a "QUIT" command to the server saying that you're disconnecting, so the server tears down its side of the socket. In general you really don't want to share a mysql connection between two processes - you'll get weird errors depending on whether the two processes are trying to use the socket at the same time.

如果关闭Redis的连接,只需关闭套接字(而不是发送我要离开消息发送到服务器),那么孩子的连接应继续努力,因为套接字不会真正被关闭

If closing a redis connection just closes the socket (as opposed to sending a "I'm going away " message to the server) then the child connection should continue to work because the socket won't actually have been closed

这篇关于叉,红宝石,ActiveRecord的和文件上叉描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆