VBA是否使用全局解释器锁定?所有解释语言都需要一种吗? [英] Does VBA use a Global Interpreter Lock? Do all interpreted languages need one?

查看:85
本文介绍了VBA是否使用全局解释器锁定?所有解释语言都需要一种吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以使用 Application.Run 方法将VBA类(COM对象)从一个托管的VBA进程传递到另一个(例如,一个Excel.exe实例传递到另一个).这意味着第二个进程(线程2)将有权访问第一个进程(线程1)中定义的代码.

It is possible to pass a VBA class (COM object) from one hosted VBA process to another (e.g. one instance of Excel.exe to another) using the Application.Run method. That means the second process (thread 2) will have access to code defined in the first process (thread 1).

因此,第二个线程可能会在线程1的对象上调用一个方法,该对象使用第一个线程的解释器运行,因此线程1的解释器同时从线程1和线程2调用.

It is therefore possible that the second thread would invoke a method on the object from thread 1 which runs using the first thread's interpreter, so thread 1's interpreter is being invoked from thread 1 and thread 2 simultaneously.

这对任何人来说都不足为奇,但是对我来说,因为VBA是作为一种单线程语言实现的(它们都在宿主应用程序的UI线程中运行!)并且没有提供编写多线程代码的语法.基于此,我认为VBA解释器肯定不是线程安全的,并且不允许其他线程执行.但是显然您可以,而且我过去也将VBA对象传递给python库(我想它可以与python解释器一起在单独的线程上运行).

That's probably not surprising to anyone, but it was to me, since VBA is implemented as a single threaded language (it all runs in the host application's UI thread!) and doesn't give you syntax to write multithreaded code. Based on that I thought surely the VBA interpreter wouldn't be thread safe and would not allow execution from other threads. But apparently you can, and I've also passed VBA objects to python libraries in the past (which I imagine run on a separate thread with the python interpreter).

那么,VBA是否具有像Python一样的GIL-意味着解释器一次只能由单个线程运行,还是发生了其他情况?有什么方法可以检查吗?

So how is it done, does VBA have a GIL like Python - meaning the interpreter can only ever be run by a single thread at a time, or is there something else going on? Is there any way to check?

推荐答案

为控制哪些线程可以访问COM对象上的方法(线程相似性),COM使用单元.公寓是放置具有相同线程相似性的对象的地方.套间专用于单个过程.

To control what threads can access methods on a COM Object (thread affinity), COM uses apartments. An apartment is a place for objects having the same thread affinity. Apartments are specific to a single process.

VBA对象具有很高的线程关联性,它们存在"于STA(单线程单元)中.他们将从始终是同一线程的单个线程接收呼叫.在VBA中,STA中只有一个线程.STA旨在防止对象并发.当线程进入STA(称为CoInitializeEx)时,将创建一个隐藏的窗口.当对驻留在STA中的对象进行调用时,会将窗口消息发布到隐藏的窗口,该窗口随后使单元中的线程执行该调用.如果有两个线程在STA中的对象上调用方法,则隐藏窗口将接收到两个消息,并且一次仅处理一个消息,这意味着第二个消息被阻塞,直到第一个调用完成为止.简而言之,生活在STA中的对象没有并发性.

VBA Objects have high thread affinity and they "live" in an STA (single threaded apartment). They will receive calls from a single thread which is always the same thread. In VBA there is one and only one thread in the STA. STA is designed to protect objects against concurrency. A hidden window is created when a thread enters an STA (CoInitializeEx is called). When a call to an object living in the STA is made, a window message is posted to the hidden window which then makes the thread in the apartment to execute the call. If two threads call methods on an object living in an STA, then the hidden window will receive two messages and only one will be handled at a time meaning that the second is blocked until the first call has completed. In short, objects living in an STA do not have concurrency.

来自另一个进程的调用不是直接调用.不同的公寓和线程.COM而是模拟一个同步调用.调用过程中的调用会暂停,然后在实际对象所在的过程中重播.COM旨在与甚至来自不同计算机的对象一起使用.模拟(或拦截)涉及代理和存根以及COM传输.

A call from another process is not a direct call. Different apartments and threads. COM simulates a synchronous call instead. The call in the calling process is paused and then replayed in the process where the actual object lives. COM is designed to work with objects even from different computers. The simulation (or interception) involves a proxy and a stub and the COM transport.

例如,如果进程1中的VBA线程(T1)使用在进程2(T2)中的VBA线程中创建的对象,则该对象的接口将从T2的单元导出到T1的单元(接口被封送).当COM封送接口时,它将在T2的单元中创建一个存根.存根代表主叫方-T1.传输编组的信息,然后将其用于在T1的单元中创建(解组)对象的接口(代理).在代理和存根之间设置了通信.因此,T1接收的是代理服务器,而不是真实的对象(该对象位于完全不同的存储空间中).当T1调用代理上的方法时,COM通过存根将调用转发到实际对象,等待直到调用完成并返回结果.

For example, if a VBA thread (T1) in process 1 uses an object created in a VBA thread in process 2 (T2), then the object’s interface is exported from the apartment of T2 to the apartment of T1 (the interface is marshalled). When COM marshals the interface, it creates a stub living in the apartment of T2. The stub represents the calling side - T1. The marshalled information is transported and then used to create (unmarshall) the object’s interface (the proxy) in the apartment of T1. Communication is set between the proxy and the stub. So, T1 receives a proxy, not the true object (which lives in a totally different memory space). When T1 calls a method on the proxy, COM forwards the call to the real object via the stub, waits until the call is done and returns the result.

这篇关于VBA是否使用全局解释器锁定?所有解释语言都需要一种吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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