Rails:调用fork()时可能正在另一个线程中

时间:2018-10-05 19:07:39

标签: ruby-on-rails

升级到OS10.14后,使用Httparty

时出现此错误。
    response = HTTParty.get('http://api.stackexchange.com/2.2/questions?site=stackoverflow')
objc[4182]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called.
objc[4182]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

我已经尝试过 export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES,然后再启动Rails控制台。

但这没用。

3 个答案:

答案 0 :(得分:9)

Ruby错误跟踪系统上有一个与此问题有关的线程!

https://bugs.ruby-lang.org/issues/14009

基本上... 您可能已经知道,在多线程环境中派生(但不执行)本质上是危险的,必须仔细编写环境以支持这种情况。传统上,Apple的Objective-C库完全不支持在派生的(但不是执行的)子进程中调用,但是自High Sierra 10.13开始,他们试图为此提供有限的支持。但是,这样做时,他们还定义了关于分叉后不允许的规则。其中一条规则指出,不允许在分叉后调用某些Objective-C类的初始化函数。可能只会在分叉之前发生。

到目前为止,都有意义。发生此问题是由于三件事的结合:

Ruby本身未链接到任何Objective-C库,因此不会自行初始化Objective-C类。 用户可以使用确实链接到Objective-C库的gem。由于这些gem的使用方式,在应用服务器分叉之后,这些gem最终可能会调用Objective-C初始化程序。 新的Apple强制性规则检查然后中止,并发出如下警告:

objc[81924]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called.
objc[81924]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

Apple的错误检查本身很有意义。分叉是危险的。但是所有这些因素加在一起就没有意义了。在Ruby中添加变通办法(以确保在派生之前调用Objective-C初始化程序的形式)至少可以确保我们返回到High Sierra之前的行为。

该线程中有很多解决方案,您将需要一个特定于您的环境/已安装的gem的解决方案。

对我有用的是export DISABLE_SPRING=true

答案 1 :(得分:7)

在Rails控制台之前运行替代方法命令是不够的。

以下解决方案对我有用(按照此说明进行操作):

如果遇到此错误,可以将下面的代码添加到主目录中的.bash_profile中,以解决此问题。

导出OBJC_DISABLE_INITIALIZE_FORK_SAFETY =是

  1. 打开您的终端机
  2. 通过键入cd〜
  3. 导航到主目录
  4. 在编辑器中打开.bash_profile(用于VS Code的代码,用于Atom,vim,nano的atom)。 纳米.bash_profile
  5. 在文件中复制并粘贴导出OBJC_DISABLE_INITIALIZE_FORK_SAFETY = YES(确保它位于文件底部RVM部分上方!)

*这很重要* 就我而言,进入.bash_profile就是这样:

...

导出OBJC_DISABLE_INITIALIZE_FORK_SAFETY =是

[[--s“ $ HOME / .rvm / scripts / rvm”]] &&来源“ $ HOME / .rvm / scripts / rvm”#加载RVM $

...

保存文件并退出所有编辑器和终端会话。 重新打开编辑器,一切正常。

我在此链接Kody Clemens Personal Blog

中找到了此解决方案

答案 2 :(得分:1)

我在OS Mojave和ruby-2.4.0上遇到了这个问题,或者我通过升级到ruby-2.4.4使它起作用。我也在这里发布了答案。 Oracle instant client with gem ruby-oci8 not able to connect with DB in rails c