UnSafe类中的CAS *** 作

UnSafe类中的CAS *** 作,第1张

CAS *** 作

是通过compareAndSwapXXX方法实现的

/**

* 比较obj的offset处内存位置中的值和期望的值,如果相同则更新。此更新是不可中断的。

*

* @param obj 需要更新的对象

* @param offset obj中整型field的偏移量

* @param expect 希望field中存在的值

* @param update 如果期望值expect与field的当前值相同,设置filed的值为这个新值

* @return 如果field的值被更改返回true

*/

public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update)

CAS *** 作有3个 *** 作数,内存值M,预期值E,新值U,如果M==E,则将内存值修改为B,否则啥都不做。

首先介绍一下什么是Compare And Swap(CAS)?简单的说就是比较并交换。

CAS *** 作包含三个 *** 作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何 *** 作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。” Java并发包(java.util.concurrent)中大量使用了CAS *** 作,涉及到并发的地方都调用了sun.misc.Unsafe类方法进行CAS *** 作。

在看一下volatile, Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的值是相同的,更简单一点理解就是volatile修饰的变量值发生变化时对于另外的线程是可见的。

如何正确使用volatile可以参考下面这篇文章:

http://www.ibm.com/developerworks/cn/java/j-jtp06197.html Java

理论与实践: 正确使用 Volatile 变量

下面来看看java中具体的CAS *** 作类sun.misc.Unsafe。Unsafe类提供了硬件级别的原子 *** 作,Java无法直接访问到 *** 作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。

此变通办法可能导致计算机或网络更容易受到攻击由恶意用户或恶意软件如病毒。 我们不建议此变通方法, 以便您可以选择来实现此解决办法由自己自行此信息仅供参考。 需要您自担风险使用此解决办法。

要使用 RDS, 必须运行 Microsoft Internet Information Services (IIS) 服务器以不安全模式。 以使 IIS 服务器运行在一个 unsafe 模式, 您必须运行 Handunsf.reg 文件随 Microsoft Data Access Components (MDAC) Redist 安装程序一起安装。 但是, 此文件已删除 MDAC 2.8 中。 默认情况下, 一起与 Microsoft Windows Server 2003 安装 MDAC 2.8。 因此, 运行 Microsoft Windows Server 2003 计算机上没有 Handunsf.reg 文件。

因此, 以使 IIS 服务器运行在一个 unsafe 模式, 其中是运行 IIS 服务的计算机管理员可以代码中使用 msdfmap.handler 并编辑 msdfmap.ini 文件以在 msdfmap.ini 文件中进行适当更改以便通过 RDS. 应用程序可以访问数据 有关删除了 MDAC 2.8, Handunsf.reg 文件请单击下列文章编号以查看 Microsoft 知识库中相应:

你好,使用golang写动态库,再使用易语言写界面,肯定有不少人有这种想法吧;但中间有些坑,这里留下一些解决方法。

一、如何编译?

请先安装gcc编译器,选择32位

由于易语言只支持32位dll,使用64位会出错,例如找不到此函数;

必须先设置两项配置:set GOARCH=386,set CGO_ENABLED=1,用cmd;

编译命令:go build -ldflags "-s -w" -buildmode=c-shared -o dlldemo.dll dlldemo.go 。

二、形参与返回值

在go中,除了 string 特殊外,其他int、bool,等基本类型原本怎样还是怎样;

传 string 与返回值 string 都改成 *C.char 类型,其他基本类型不用改;

有三个方法比较重要,C.CString 转成c字符串,C.GoString 转成go字符串 , C.free 释放内存;

只要用到 C.CString 此方法,就必须记得释放内存。

三、内存泄漏

如果使用了 C.CString 却不使用 C.free ,内存暂用只会越来越大,最后奔溃;

释放内存时,请不要重复取地址,例如 unsafe.Pointer(&xx变量) ,这样等于没释放;

也可能是vc6的原因,使用 defer 在即将出栈时释放,会造成易语言得不到返回值;

解决方法,声明全局变量,将结果赋值给全局变量,专门定义一个释放函数例如FreeAll() 用于释放!

四、如何调用

在填写dll命令时,请在填写,在库中对应命令名时,前面加个 @ ,不然会出现栈错误;

每次调用返回值是文本型dll命令时,请都使用前面准备的 FreeAll() 释放内存!

通过易语言的便捷,为自己的golang小项目加点gui吧,这里留下源码,给有需要的人。

希望能帮到你。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/7857348.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存