erl_ddll
erl_ddll
模块
erl_ddll
模块摘要
动态驱动程序加载程序和链接器。
描述
该模块提供了一个装卸界面。Erlang连接驱动程序
在运行时。
注
这是一份大型参考文件。对于本模块的临时使用,以及大多数实际应用程序,对函数的描述load/2
和unload/1
已经足够开始了。
驱动程序将以特定于所使用平台的对象代码格式作为动态链接库提供,即,.so
大多数Unix系统上的文件和.ddl
一个Erlang链接驱动程序必须为模拟器提供特定的接口,所以这个模块不是为加载任意的动态库而设计的。有关Erlang驱动程序的更多信息,请参见erts:erl_driver
...
当描述一组函数(即模块,模块或应用程序的一部分),在进程中执行并希望使用ddll驱动程序时,我们使用术语user
。一个进程可以有许多用户
(不同的模块需要相同的驱动程序)和许多进程运行相同的代码,组成许多用户
的驱动程序。
在基本场景中,每个用户在开始使用驱动程序之前加载驱动程序,完成后卸载驱动程序。引用计数跟踪每个进程的进程和负载数。这样,只有当没有人想要驱动程序时,才会卸载它--它没有用户%29。驱动程序还跟踪向其开放的端口。这样可以延迟卸载,直到所有端口关闭,或者在卸载时关闭使用驱动程序的所有端口。
该接口支持两种基本的加载和卸载场景。每个场景还可以选择在驱动程序卸载时关闭端口,或者等待端口自行关闭。设想情况如下:
按“需要时”装卸
这种(最常见的)方案仅支持每个user
驱动程序在需要时加载它,并在不再需要时卸载它。驱动程序始终是参考计数的,只要保持驱动程序加载的进程仍然存在,驱动程序就存在于系统中。
各user
司机使用字面上
在要求加载时,驱动程序的路径名称相同,但是users
与驱动程序是否已从文件系统加载或必须从文件系统加载目标代码无关。
以下两对函数支持此场景:
装载/2和卸载/1
当使用load/unload
接口时,驱动程序才会卸载,直到最后端口
使用驱动程序是关闭的。功能unload/1
可以立即返回,因为users
卸货发生时,不得有中间休息。当没有人需要的时候,司机就被卸下了。
如果加载了驱动程序的进程死了,它的效果与完成卸载的效果相同。
加载时,当驱动程序的任何实例存在时函数会load/2
返回ok
。因此,如果驾驶员等待卸载(由于开放端口),它只是将状态改变为不再需要卸载。
load_driver / 2和unload_driver / 1
当认为端口向驱动程序打开时,如果没有端口,则应使用这些接口。user
已经装好了。上一次访问时仍然打开的端口。user
打电话unload_driver/1
或者当最后一个加载驱动程序的进程死掉时,都会有原因地终止。driver_unloaded
...
函数名load_driver
和unload_driver
为了向后兼容性而保留。
代码替换的加载和重新加载
如果在Erlang模拟器的操作期间需要替换驱动程序代码,则可能发生此情况。实现驱动程序代码替换比梁代码替换稍微繁琐一些,因为一个驱动程序不能同时作为“旧”和“新”代码加载。全users
在卸载旧代码和加载新代码之前,驱动程序必须关闭%28no打开端口%29。
卸载/加载是作为一个原子操作完成的,阻止系统中的所有进程在执行过程中使用所述驱动程序。
替换驱动程序代码的首选方法是一个过程
跟踪司机。当进程启动时,将加载驱动程序。当需要更换时,重新加载驱动程序。卸载可能从未完成,或者在进程退出时完成。如果不止一个user
在需要替换代码时加载驱动程序,替换直到最后一个“其他”时才会发生。user
已经卸载了司机。
当重新加载已经在进行时,要求重新加载始终是一个错误。使用高级函数时,当需要重新加载多个函数时,要求重新加载也是一个错误。user
司机上膛了。
若要简化驱动程序替换,请避免设计您的系统,以使多个驱动程序替换。user
司机上膛了。
用于重新加载驱动程序的两个函数将与相应的加载函数一起使用,以支持与开放端口有关的两种不同行为:
负载/2和重装/2
这对函数用于在最后一个打开驱动程序的端口关闭后重新加载时使用。
当reload/2
等待重新加载发生时,为驱动程序保持打开端口(或保持驱动程序加载)的行为不当操作会导致无限等待重新加载。超时必须在要求重新加载的过程之外提供,或者通过try_load/3
与驱动程序监视器结合使用低级界面。
load_driver / 2和reload_driver / 2
这对函数是在为驱动程序打开端口时使用的。driver_unloaded
允许加载新的驱动程序代码。
但是,如果另一个进程加载了驱动程序,则调用reload_driver
返回错误码pending_process
如上文所述,建议的设计是不允许其他users
比“驱动程序重装器”要求加载驱动程序的问题。
数据类型
driver() = iolist() | atom()
path() = string() | atom()
出口
demonitor(MonitorRef) -> ok
类型
移除驱动程序监视器的方式与erlang:demonitor/1
在ERTS中使用进程监视器。有关如何创建驱动程序监视器的详细信息,请参阅monitor/2
,,,try_load/3
,和try_unload/2
...
函数抛出一个badarg
如果参数不是reference()
...
format_error(ErrorDesc) -> string()
类型
采取ErrorDesc
由加载、卸载或重新加载函数返回,并返回描述错误或警告的字符串。
注
由于在不同平台上的动态加载接口的特殊性,如果在Erlang虚拟机的同一实例中调用format_error / 1
,则返回的字符串只能保证描述正确的错误,因为错误出现在
(意味着相同的操作系统进程)。
INFO%28%29->AllInfoList
类型
返回元组列表。{DriverName, InfoList}
,在哪里InfoList
是调用的结果info/1
为了那个DriverName
只有动态链接的驱动程序才被包括在列表中。
info(Name) -> InfoList
类型
返回元组列表。{Tag, Value}
,在哪里Tag
是信息项和Value
是调用的结果info/2
有这个司机的名字和这个标签。结果是一个包含有关驱动程序的所有可用信息的元组列表。
列表中显示了以下标记:
processes
driver_options
port_count
linked_in_driver
permanent
awaiting_load
awaiting_unload
有关每个值的详细说明,请参见info/2
...
函数抛出一个badarg
如果系统中不存在驱动程序,则为例外。
info(Name, Tag) -> Value
类型
返回有关驱动程序某一方面的特定信息。参数Tag
指定要获取有关信息的方面。回报Value
不同标签之间的差异:
processes
返回包含users将特定驱动程序作为元组列表。{pid(),integer() >= 0},在哪里integer()表示进程中的用户数。pid()...
driver_options
返回加载时提供的驱动程序选项列表,以及在初始化过程中由驱动程序设置的任何选项。唯一有效的选择是kill_ports
...
port_count
integer() >= 0使用驱动程序返回端口(an )的数量。
linked_in_driver
返回boolean()
,也就是true
如果驱动程序是静态链接的,则为false
...
permanent
返回boolean()
,true
如果驱动程序已使其自身成为永久(并且不是
静态链接的驱动程序),则返回a ,否则false
。
awaiting_load
返回具有监视器的所有进程的列表。loading活动。每个进程返回为{pid(),integer() >= 0},在哪里integer()是进程所持有的监视器数量。pid()...
awaiting_unload
返回具有监视器的所有进程的列表。unloading活动。每个进程返回为{pid(),integer() >= 0},在哪里integer()是进程所持有的监视器数量。pid()...
中频选项linked_in_driver
或permanent
回报true
,所有其他选项返回linked_in_driver
或permanent
分别。
函数抛出一个badarg
如果驱动程序不存在于系统中或不支持标记,则为例外。
load(Path, Name) -> ok | {error, ErrorDesc}
类型
加载并链接动态驱动程序Name
...Path
是指向包含驱动程序的目录的文件路径。Name
必须是可共享的对象/动态库。两个不同的司机Path
参数不能以相同的名称加载。Name
包含至少一个字符的字符串或原子。
所述Name
指定的是对应于驻留在指定为目录可动态加载的对象文件的文件名Path
,但没有
所述延伸部(即,.so
)。驱动程序初始化例程中提供的驱动程序名称必须与文件名相对应,这与Erlang模块名称与.beam
文件名称相对应的方式相同。
如果驱动程序先前已卸载,但由于端口已打开而仍然存在,因此会load/2
停止卸载并保留驱动程序(只要Path
是相同的),然后ok
返回。如果您确实想要重新加载对象代码,请改为使用reload/2
低级接口try_load/3
。请参阅介绍中different scenarios
有关加载/卸载的说明。
如果多个进程尝试用相同的方法加载已经加载的驱动程序Path
,或者如果同一个进程多次尝试加载它,则函数将返回ok
。模拟器跟踪load/2
调用,因此相应的数目unload/2
在卸载驱动程序之前,必须从同一进程执行调用。因此,应用程序在需要时加载进程或应用程序之间共享的驱动程序是安全的。它可以安全卸载,而不会给系统的其他部分带来麻烦。
不允许加载多个同名但不同的驱动程序。Path
参数。
注
Path
按字面解释,以便同一驱动程序的所有加载程序必须指定相同的文字
Path
字符串,尽管不同的路径可指出文件系统中的相同目录(因为使用相对路径和链接)。
成功后,该函数将返回ok
失败时,返回值为{error,ErrorDesc}
,在哪里ErrorDesc
是一个不透明的术语,可以通过函数转换为人类可读的形式。format_error/1
...
有关对错误处理的更多控制,请使用try_load/3
接口代替。
函数抛出一个badarg
如果参数未按此处描述的方式指定,则为例外。
load_driver(Path, Name) -> ok | {error, ErrorDesc}
类型
基本上起作用load/2
,但用其他选项加载驱动程序。driver_unloaded
卸载驱动程序时,所有使用该驱动程序的端口都会被原因终止。
按不同方式加载和卸载的数量users
影响驱动文件的加载和卸载。因此,只有在最后
user
卸载驱动程序,或者上次加载驱动程序的进程退出时。
为了向后兼容,保留此接口%28或至少保留函数%29的名称。使用try_load/3
带着{driver_options,[kill_ports]}
在选项列表中,对于端口终止也会产生同样的效果。
函数抛出一个badarg
如果参数未按此处描述的方式指定,则为例外。
loaded_drivers() -> {ok, Drivers}
类型
返回所有可用驱动程序的列表,包括(静态)链接和动态加载的驱动程序。
由于历史原因,驱动程序名称作为字符串列表而不是原子列表返回。
有关驱动程序的详细信息,请参阅info
...
monitor(Tag, Item) -> MonitorRef
类型
创建驱动程序监视器,并以多种方式工作erlang:monitor/2
在ERTS中,DO用于进程。当驱动程序更改状态时,监视器将生成发送到调用进程的监视器消息。MonitorRef
此函数返回的消息包含在发送的消息中。
与进程监视器一样,每个驱动程序监视器集只生成一条消息
在发送消息后,监视器被“销毁”,因此不需要调用它。demonitor/1
...
MonitorRef
也可用于后续调用demonitor/1
移除监视器。
该函数接受以下参数:
Tag
监视器标记总是driver
,因为此函数只能用于创建驱动程序监视器。将来,驱动程序监视器将与进程监视器集成,为什么必须为一致性指定此参数。
Item
参数Item
指定要监视哪个驱动程序(驱动程序名称)以及要监视哪个状态更改。参数是元组2,元素的第一个元素是驱动程序名称,第二个元素是以下之一:
loaded
当驱动程序重新加载时通知(或者如果正在加载,则加载)。监控正在加载或重新加载的驱动程序才有意义。未来的加载驱动程序名称不能被监控。这只会导致DOWN
立即发送消息。因此,监控装载在功能触发时非常有用try_load/3
,因为
驱动程序处于未决状态,因此创建监控程序。
设置驱动程序监视器loading
最终导致发送以下消息之一:
{'UP', reference(), driver, Name, loaded}
如果驱动程序已经加载,并且没有重新加载挂起,则立即发送此消息,或者在重新加载挂起时执行重新加载。
该user
预计知道,如果重新装入加载创建显示器前要求。
{'UP', reference(), driver, Name, permanent}
如果需要重新加载,则会发送此消息,但在重新加载之前(旧)驱动程序已自行永久。如果驱动程序在尝试创建显示器时是永久性的或静态链接的,它也会被发送。
{'DOWN', reference(), driver, Name, load_cancelled}
如果重新加载正在进行,此消息到达,但请求在重新加载前user
通过死亡或再次呼叫try_unload/2
(或unload/1
/ unload_driver/1
)来取消。
{'DOWN', reference(), driver, Name, {load_failure, Failure}}
如果正在重新加载,但由于某种原因的加载失败,则此消息到达。该Failure
术语是可从中返回的错误之一try_load/3
。误差项可以传递给format_error/1
翻译成人类可读的形式。请注意,必须在检测到错误的同一Erlang虚拟机中完成翻译。
**`unloaded`**
当司机卸货时监视。如果监视系统中不存在的驱动程序,则立即通知该驱动程序已卸载。不能保证司机上过车。
卸载的驱动程序监视器最终导致发送以下消息之一:
{'DOWN', reference(), driver, Name, unloaded}
监视的驱动程序实例现在已卸载。因为卸载可能是reload/2
请求时,驱动程序可以在此消息到达时再次加载。
{'UP', reference(), driver, Name, unload_cancelled}
如果期望卸载,则发送此消息,但当驱动程序等待所有端口关闭时,将发出一个新的user
司机出现了,卸货取消了。
如果{ok, pending_driver}
从try_unload/2
最后一次user
司机,然后{ok, already_loaded}
的调用返回。try_load/3
...
如果一个真的
希望监视驱动程序卸载时,此消息会扭曲图片,因为没有卸载。期权unloaded_only
创建类似于unloaded
监视器,但永远不会产生此消息。
{'UP', reference(), driver, Name, permanent}
如果期望卸载,则发送此消息,但驱动程序在卸载之前使自己永久化。如果试图监视永久或静态链接的驱动程序,也会发送它。
**`unloaded_only`**
创建的监视器的unloaded_only
行为与创建的监视器的行为完全相同,unloaded
除了{'UP', reference(), driver, Name, unload_cancelled}
不会发送消息,但监视器会一直保留,直到驱动程序真正
卸载。
函数抛出一个badarg
如果参数未按此处描述的方式指定,则为例外。
reload(Path, Name) -> ok | {error, ErrorDesc}
类型
重新加载名为Name
从一个可能不同的Path
比以前用过。此函数用于代码更改。scenario
在导言中进行了描述。
如果还有其他users
在这个驱动程序中,函数返回{error, pending_process}
但是,如果没有其他用户,则函数调用将挂起,直到所有打开的端口关闭。
注
避免混合多次users
驱动程序重新加载请求。
若要避免挂在打开的端口上,请使用函数。try_load/3
相反。
该Name
和Path
参数具有完全相同的含义调用纯函数时,同样作为load/2
。
成功后,该函数将返回ok
失败时,该函数返回一个不透明错误,但pending_process
前面描述的错误。不透明的错误将通过函数转换为人类可读的形式。format_error/1
...
有关对错误处理的更多控制,请使用try_load/3
接口代替。
函数抛出一个badarg
如果参数未按此处描述的方式指定,则为例外。
reload_driver(Path, Name) -> ok | {error, ErrorDesc}
类型
完全一样reload/2
,但是对于加载了load_driver/2
接口。
由于这个接口意味着当最后一个用户消失时端口会被杀死,所以函数不会挂起等待端口关闭。
有关详细信息,请参阅scenarios
在本模块描述和功能描述中reload/2
...
函数抛出一个badarg
如果参数未按此处描述的方式指定,则为例外。
try_load(Path, Name, OptionList) ->
{OK,Status}
{OK,PendingStatus,Ref}
{Error,ErrorDesc}
类型
提供比load/2
/reload/2
和load_driver/2
/reload_driver/2
接口。它从不等待与驱动程序相关的其他操作的完成,而是立即将驱动程序的状态返回为下列之一:
{ok, loaded}
该驱动程序已加载并立即可用。
{ok, already_loaded}
驱动程序已经由另一个进程加载,或者正在由一个活端口使用,或者两者兼而有之。您的负载已注册,并相应地try_unload
将来的某个时候。
{ok, pending_driver}
%2A%2A
或%2A%2A
{ok, pending_driver, reference()}
加载请求已注册,但由于驱动程序的较早实例仍在等待卸载(打开的端口使用它),因此加载被延迟。不过,当您完成驱动程序后,仍然会卸载。该返回值大多
发生在选项{reload,pending_driver}
或{reload,pending}
被使用,但是可以
当另一个发生user
正在卸载并联和驱动器选项的驱动器kill_ports
被设置。换句话说,这个返回值总是需要处理。
{ok, pending_process}**
或**{ok, pending_process, reference()}
加载请求已注册,但由于先前的驱动程序实例仍在等待由另一个实例卸载user
(不仅
是端口,在这种情况下{ok,pending_driver}
将被返回),因此加载被延迟。不过,当您完成驱动程序后,仍然会卸载。该返回值仅
在使用选项时发生{reload,pending}
。
当函数返回时{ok, pending_driver}
或{ok, pending_process}
,您可以获得有关司机何时是其实
使用选项加载{monitor, MonitorOption}
...
当请求监视时,相应的{ok, pending_driver}
或{ok, pending_process}
,则该函数将返回一个元组。{ok, PendingStatus, reference()}
然后,当驱动程序加载时,进程将得到一条监视器消息。的函数描述中描述了要期待的监视消息。monitor/2
...
注
在加载的情况下,监视可以不
只能通过使用选项触发{reload, ReloadOption}
,但也适用于负载误差为瞬态的特殊情况。因此,{monitor, pending_driver}
基本上是用在全
现实世界的环境。
该函数接受以下参数:
Path
驱动程序对象文件所在目录的文件系统路径。目标文件的文件名(减号扩展名)必须与驱动程序名称(在参数中使用)相对应,并且驱动Name
程序必须使用相同的名称标识自己。Path
可以作为iolist()提供
,意味着它可以是其他iolist()
s,字符(8位整数)或二进制文件的列表,所有这些都可以被拼合成一系列字符。
Path
整个系统中(可能展平)参数必须一致。所有的驱动程序users
都要使用相同的文字
加载Path
。例外情况是请求重新加载
时,在这种情况下Path
可以指定不同的情况。请注意,以后所有users
试图加载驱动程序的用户都需要使用新的
Path
if如果Path
使用reload
选项进行更改。这是只有
一个想要在运行系统中升级的驱动程序的加载程序
的另一个原因。
Name
该参数是要erlang:open_port
在ERTS 中的后续调用中使用的驱动程序的名称。该名称可以被指定为一个iolist()
或一个atom()
。加载时指定的名称用于查找目标文件(借助Path
和系统隐含的扩展后缀,即.so
)。驱动程序标识自身的名称也必须与此Name
参数一致,就像Beam文件的模块名称与其文件名非常相似。
OptionList
可以指定一些选项来控制加载操作。这些选项被指定为一个由两个元组组成的列表。元组具有以下价值和意义:
{driver_options, DriverOptionList}
这是为了提供改变其一般行为并在整个使用寿命期间“坚持”给驾驶员的选项。
指定驱动程序名称的驱动程序选项必须始终保持一致,即使在重新加载驱动程序时
这意味着他们既是司机的一部分,也是名字的一部分。
唯一允许的驱动程序选项是kill_ports
,这意味着所有向驱动程序开放的端口都会因退出原因而被关闭。driver_unloaded
当不再加载驱动程序的进程时。这种情况是在最后一个user
打电话try_unload/2
,或者上次加载驱动程序的进程何时退出。
{monitor, MonitorOption}
MonitorOption
告诉try_load/3
在特定条件下触发驾驶员监视器。当监视器被触发时,该函数返回一个三元组{ok, PendingStatus, reference()}
,其中reference()
是驱动程序监视器的监视器参考。
只有一个MonitorOption
可以指定。它是下列之一:
- 原子
pending
,这意味着每当加载操作延迟时,都要创建监视器,
- 原子
pending_driver
中,每当操作因打开端口而延迟时,就会创建监视器。
该选项pending_driver
没有什么用处,但是为了完整性而存在,因为它明确地定义哪些重新加载选项会导致哪些延迟。然而,它可以使用相同的一个好主意,MonitorOption
因为ReloadOption
如果存在的话,。
如果不要求重新加载,这仍然可能是有用的指定选项monitor
,如强制卸载(驱动器选项kill_ports
或选项kill_ports
来try_unload/2
)引发地方,直到所有关闭端口被关闭无法进行驱动程序加载的临时状态。因此,try_unload
在几乎所有情况下,都可以返回{ok, pending_driver}
,至少{monitor, pending_driver}
在生产代码中至少指定(请参阅前面的监视器讨论)。
{reload, ReloadOption}
此选项用于再装
来自磁盘的驱动程序,通常是在代码升级场景中。有reload
选项还意味着该参数Path
是吗?不
需要与先前的驱动程序负载保持一致。
若要重新加载驱动程序,进程必须在此之前加载驱动程序,也就是说,必须有活动的驱动程序。user
在过程中的司机。
该reload
选项可以是以下任一项:
pending
用原子pending
,将为任何驱动程序请求重新加载,并在全
向驱动程序开放的端口被关闭。在这种情况下,无论是否仍有待机,驱动程序替换都会发生。users
开了车。
该选项也会触发端口查杀(如果使用了驱动程序选项kill_ports
),虽然有未决用户,使其可用于强制更换驱动程序,但对驱动程序承担了很大的责任users
。待定选项很少使用,因为users
当代码更改正在进行时,不希望其他人加载驱动程序。
pending_driver
这个选项更有用。在这里,如果驱动程序没有
被其他任何驱动程序加载users
,但是驱动程序已经打开了端口,在这种情况下{ok, pending_driver}
返回(monitor
推荐使用一个选项),重新加载是排队的。
如果驱动程序已卸载(不存在于系统中),not_loaded
则返回错误代码。该选项reload
适用于用户已经预先加载驱动程序的情况。
函数可以返回许多错误,有些只能返回给定的组合选项。
有些错误是不透明的,只能通过将它们传递给函数来解释。format_error/1
,但有些可以直接解释:
{error,linked_in_driver}
具有指定名称的驱动程序是一个Erlang静态链接的驱动程序,它不能使用此API进行操作。
{error,inconsistent}
驱动程序已经装载了其他DriverOptionList
或者是另一种文字
Path
争论。
即使在reload
选项,如果DriverOptionList
与电流不同。
{error, permanent}
驱动程序要求自己是永久的,使其行为像Erlang链接的驱动程序,并且不能再使用这个API操作。
{error, pending_process}
驱动程序由其他users
何时选择{reload, pending_driver}
具体说明。
{error, pending_reload}
另一个已请求重新加载驱动程序。user
何时选择{reload, ReloadOption}
具体说明。
{error, not_loaded_by_this_process}
选项时出现reload
被指定。司机Name
存在于系统中,但没有user
在这个过程中。
{error, not_loaded}
选项时出现reload
被指定。司机Name
不在系统里。只有通过此进程加载的驱动程序才能重新加载。
所有其他错误代码都将通过函数转换。format_error/1
.注意到format_error
将从Erlang虚拟机的同一个运行实例中执行,因为错误值与系统相关。
如果参数或选项格式错误,则函数将引发badarg
例外。
try_unload(Name, OptionList) ->
{OK,Status}
{OK,PendingStatus,Ref}
{Error,ErrorAtom}
类型
这是卸载驱动程序(或减少引用计数)的低级函数。它可以用来强制端口查杀,就像驱动程序选项kill_ports
隐含的那样。此外,它可以触发监视器,因为其他users
驱动程序仍然会加载驱动程序,或者因为打开的端口使用驱动程序。
卸载可以被描述为告诉模拟器这个特定的过程(即这个user
)中的代码的特定部分不再需要驱动程序的过程。如果没有其他用户,则可以触发卸载驱动程序,在这种情况下,驱动程序名称会从系统中消失,并且(如果可能)会收回驱动程序可执行代码占用的内存。
如果驱动程序kill_ports
设置了选项,或者kill_ports
将此选项指定为此功能的选项,则使用此驱动程序的所有待处理端口在卸载完成时都将被终止user
。如果不涉及端口查杀并且存在开放端口,则卸载将延迟到不再有开放端口使用该驱动程序。如果在这种情况下,另一个user
(甚至是该用户)在卸载驱动程序之前再次加载驱动程序,卸载永远不会发生。
若要允许user
到请求卸载
等待实际卸载
,,,monitor
触发器可以与加载时相同的方式指定。然而,作为users
在这个功能中,很少有兴趣比减少引用数更感兴趣,很少需要进行监测。
注
如果使用选项kill_ports
,监视器触发是至关重要的,因为在卸载驱动程序之前不保证端口被杀死。因此,至少必须触发监视器pending_driver
。
要期待的可能监视消息与使用选项时相同。unloaded
起作用monitor/2
...
函数在成功时返回下列状态之一:
{ok, unloaded}
驱动程序立即卸载,这意味着驱动程序名称现在可以由其他驱动程序自由使用,如果底层操作系统允许使用,则驱动程序对象代码占用的内存现在被回收。
只有当没有打开的端口并且不再使用它时,才能卸载驱动程序。users
要求它装上子弹。
{ok, pending_driver}**
或**{ok, pending_driver, reference()}
指示此调用删除了最后一个user
但是仍然有开放的端口在使用它。当所有端口都关闭并且没有新的端口时users
已经到达,驱动程序将被重新加载,并恢复名称和内存。
即使选项,此返回值也是有效的。kill_ports
使用,因为杀死端口可能是不立即完成的进程。然而,在这种情况下,情况是暂时的。监视器对于检测驱动程序何时真正卸载总是很有用的。
{ok, pending_process}
%2A%2A
或%2A%2A
{ok, pending_process, reference()}
卸载请求已注册,但其他users
还抱着司机。注意这个词pending_process
可以引用正在运行的进程;可以有多个进程。user
在同一过程中。
这是一个正常的、健康的、返回值,如果调用只是为了通知模拟器您没有进一步使用驱动程序。它是最常见的返回值。scenario
在导言中进行了描述。
该函数接受以下参数:
Name
Name
要卸载的驱动程序的名称。名称可以指定为iolist()
或者作为一个atom()
...
OptionList
OptionList
在某些情况下,参数可用于指定有关端口和触发监视器的某些行为:
kill_ports
driver_unloaded
如果您是驱动程序的最后一位
,则强制使用此驱动程序打开所有打开的端口,并退出原因user
。
如果其他users
加载驱动程序,此选项没有任何效果。
为了在上次user
卸载时获得终止端口的一致行为,请kill_ports
在加载驱动程序时使用驱动程序选项。
{monitor, MonitorOption}
如果指定的条件MonitorOption
为true ,则创建驱动程序监视器。有效的选项是:
pending_driver
如果返回值为{ok, pending_driver}
...
pending
如果返回值为{ok, pending_driver}
或{ok, pending_process}
...
这pending_driver
MonitorOption
是迄今为止最有用的。它必须用于确保驱动程序真正卸载并且端口在使用选项时关闭kill_ports
,或者驱动程序可以装入驱动程序选项kill_ports
。
调用中使用监视器触发器。try_unload
确保在执行卸载之前添加监视器,这意味着监视器总是被正确触发,如果monitor/2
单独调用。
该函数可以返回以下错误条件,所有指定的%28no不透明值%29:
{error, linked_in_driver}
您试图卸载Erlang静态链接的驱动程序,该驱动程序无法使用此界面进行操作(并且根本无法卸载)。
{error, not_loaded}
该驱动程序Name
不在系统中。
{error, not_loaded_by_this_process}
Name
系统中存在驱动程序,但user
在此过程中没有驱动程序。
作为特例,驱动程序可以从没有执行相应调用的进程中卸载。try_load/3
如果,而且只有当根本没有驱动程序的用户。
,如果包含最后一个用户的进程死了,就会发生这种情况。
{error, permanent}
驱动程序已使其自身成为永久性的,在这种情况下,它不能再由此界面操作(很像静态链接驱动程序)。
函数抛出一个badarg
如果参数未按此处描述的方式指定,则为例外。
卸载(Name) - > ok | {error,ErrorDesc}
类型
卸载,或者至少取消名为Name
如果打电话的人是最后一个user
在驱动程序中,并且不再有打开的端口使用驱动程序,驱动程序将被卸载。否则,卸货将延迟,直到所有港口关闭,而没有。users
留下来。
如果还有其他users
在驱动程序中,仅减少驱动程序的引用数,因此调用方不再被视为user
司机的照片。有关使用方案,请参见description
在这个模块的开头。
在ErrorDesc
返回的是要在发挥功能进一步传递一个不透明的价值format_error/1
。要更多地控制操作,请使用try_unload/2
界面。
函数抛出一个badarg
如果参数未按此处描述的方式指定,则为例外。
unload_driver(Name) -> ok | {error, ErrorDesc}
类型
卸载,或者至少取消名为Name
如果打电话的人是最后一个user
在驱动程序中,所有剩余的使用驱动程序的开放端口都是有原因的被杀死的。driver_unloaded
司机最终会卸货。
如果还有其他users
在驱动程序中,仅减少驱动程序的引用数,因此调用方不再被视为user
有关使用方案,请参见description
在这个模块的开头。
在ErrorDesc
返回的是要在发挥功能进一步传递一个不透明的价值format_error/1
。要更多地控制操作,请使用try_unload/2
界面。
函数抛出一个badarg
如果参数未按此处描述的方式指定,则为例外。