Delphi原子操作函数介绍
一、Delphi的原子操作函数
在System.SyncObjs单元中,有一个TInterlocked的密封类,其十多个类函数(class function)其实都是调用的System单元的原子操作函数,只是封装得更容易理解。
使用方法:如对一个数值加一,则直接b:= TInterlocked.Increment(a);或TInterlocked.Increment(a);,不用创建TInterlocked类(类函数相当于就是单独的函数,可以直接调用,不用实例化对象)
1、对一个数值变量加一和减一操作
//实际是调用System单元的AtomicIncrement函数
//对Target加一,并返回加一后的结果
class function Increment(var Target: Integer): Integer; overload; static; inline;
class function Increment(var Target: Int64): Int64; overload; static; inline;
//对Target减一,并返回减一后的结果
class function Decrement(var Target: Integer): Integer; overload; static; inline;
class function Decrement(var Target: Int64): Int64; overload; static; inline;
实例一:
var
a,b:integer;
begin
a:=1;
b:= TInterlocked.Increment(a);
//则b=2(等于a加一后的结果),同时a=2(a=1+1),而这时的a加一是原子操作,不会受多线程影响,能够保证数据一致性。
end;
2、对一个数值、指针、对象地址、泛型类的地址进行替换操作
//将Target替换为Value,并返回原来的Target值
//实际是调用System单元的AtomicExchange函数
class function Exchange(var Target: Pointer; Value: Pointer): Pointer; overload; static; inline;
class function Exchange(var Target: Integer; Value: Integer): Integer; overload; static; inline;
class function Exchange(var Target: Int64; Value: Int64): Int64; overload; static; inline;
class function Exchange(var Target: TObject; Value: TObject): TObject; overload; static; inline;
class function Exchange(var Target: Double; Value: Double): Double; overload; static; inline;
class function Exchange(var Target: Single; Value: Single): Single; overload; static; inline;
class function Exchange<T: class>(var Target: T; Value: T): T; overload; static; inline;
实例二:
var
a,b,c:integer;
begin
a:=1;
b:=2;
c:= TInterlocked.Exchange(a,b);
//则c=1(等于a之前的值),同时a=2(a被替换成b的值),而这时的a是原子操作,不会受多线程影响,能够保证数据一致性。
end;
3、比较两个值,相同时,用一个值替换掉目标值
//比较Target与Comparand两个值,当两个值相等,则将Target的值替换为Value的值,这个过程非常重要,是实现原子锁的核心
//实际是调用System单元的AtomicCmpExchange函数
class function CompareExchange(var Target: Pointer; Value: Pointer; Comparand: Pointer): Pointer; overload; static; inline;
class function CompareExchange(var Target: Integer; Value: Integer; Comparand: Integer): Integer; overload; static; inline;
class function CompareExchange(var Target: Integer; Value: Integer; Comparand: Integer; out Succeeded: Boolean): Integer; overload; static;
class function CompareExchange(var Target: Int64; Value: Int64; Comparand: Int64): Int64; overload; static; inline;
class function CompareExchange(var Target: TObject; Value: TObject; Comparand: TObject): TObject; overload; static; inline;
class function CompareExchange(var Target: Double; Value: Double; Comparand: Double): Double; overload; static; inline;
class function CompareExchange(var Target: Single; Value: Single; Comparand: Single): Single; overload; static; inline;
class function CompareExchange<T: class>(var Target: T; Value: T; Comparand: T): T; overload; static; inline;
这里要分成比较值相等和不相等两种情况
实例三:
var
a,b,c,d,e:integer;
begin
a:=1;
b:=2;
c:=3;
e:=1;
//比较a与c的值是否相等,相等则用b的值替换掉a的值,不相等则不替换
//由于a等于e(都等于1),则a的值被替换成b的值,即a=2,同时d等于a原来的值,即d=1
d:=TInterlocked.CompareExchange(a,b,e);
//由于a不等于c的值,所以a不会被替换,则d=1(等于a的值)
d:= TInterlocked.CompareExchange(a,b,c);
//注意了,不管a是否等于c和e的值,返回的一定是a原来的值,这个特性非常容易让我们判断a值到底是多少。
end;
4、用原子操作性读取一个数值
//如果在32位多线程中直接读取一个64位变量,寄存器是分为高字节和低字节两个部分,会读到脏数据,用原子操作读取则不会
class function Read(var Target: Int64): Int64; static; inline;
实际是调用System单元的AtomicExchange函数,如:b:=AtomicExchange(a,0,0);,始终会取到a原来的值,所以并不限于int64类型。
Delphi原子操作函数介绍的更多相关文章
- [原创] Delphi Win API函数 操作帮助文件 HtmlHelpA函数介绍
Delphi Win API函数 操作帮助文件 HtmlHelpA函数介绍 函数原型:HWND HtmlHelpA( HWND hwndCaller, LPCSTR pszFile, UINT uCo ...
- Delphi TStream 详细介绍
Delphi TStream 详细介绍Stream对象,又称流式对象,是TStream.THandleStream.TFileStream.TMemoryStream.TResourceStream和 ...
- python strip()函数 介绍
python strip()函数 介绍,需要的朋友可以参考一下 函数原型 声明:s为字符串,rm为要删除的字符序列 s.strip(rm) 删除s字符串中开头.结尾处,位于 rm删除 ...
- PHP ob_start() 函数介绍
ob_start() 函数介绍: http://www.nowamagic.net/php/php_ObStart.php ob_start()作用: http://zhidao.baidu.com/ ...
- delphi公共函数 UMyPubFuncFroc--版权所有 (C) 2008 勇者工作室
{*******************************************************} { } { Delphi公用函数单元 } { } { 版权所有 (C) 2008 勇 ...
- Python开发【第三章】:Python函数介绍
一. 函数介绍 1.函数是什么? 在学习函数之前,一直遵循面向过程编程,即根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复 ...
- row_number() OVER(PARTITION BY)函数介绍
OVER(PARTITION BY)函数介绍 开窗函数 Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个 ...
- select与poll函数介绍
select与poll函数介绍 在所有依从POSIX的平台上,select函数使我们可以执行I/O多路转接.传向select的参数告诉内核: 1)我们所关心的描述符 2)对于每个描述符我们所关心的状态 ...
- swift1.2语言函数和闭包函数介绍
swift1.2语言函数和闭包函数介绍 在编程中,随着处理问题的越来越复杂,代码量飞速增加.其中,大量的代码往往相互重复或者近似重复.如果不采有效方式加以解决,代码将很难维护. swift1.2语言函 ...
- ZLG_GUI配置与函数介绍
http://www.docin.com/p-825479457.html ZLG_GUI配置与函数介绍
随机推荐
- C# 从桌面右下角显示 Popup 窗口提醒
上图演示 private void display_Click(object sender, EventArgs e) { Frm_Info.Instance().ShowForm();//显示窗体 ...
- Go ASM 学习笔记之 ppt 版
在 小白学标准库之反射 reflect 篇中介绍了接口和反射.然而,对于接口的类型转换,底层实现还是一知半解.在参考 Go 语言设计与实现 这本书接口章节时,又看不大懂.一个拦路虎摆在面前:汇编.不懂 ...
- Java标签在循环中的使用
定义 标签,类似--label1: 放在循环外部,用于内部多重循环语句的跳出 例子 public static void main(String[] args) { Scanner sc = new ...
- js - body的滚动事件的坑
文章来源 : https://www.cnblogs.com/Zting00/p/7497629.html 踩过些坑,得到的结论,不一定精确 1. body的滚动条,刷新页面的时候不会回到顶部.其他d ...
- [转帖]快速入门:在 Red Hat 上安装 SQL Server 并创建数据库
https://learn.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-red-hat?view=sql-server-linux ...
- [转帖]datax安装+配置+使用文档
1 DataX离线同步工具DataX3.0介绍 DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL.Oracle.SqlServer.Postgre.HDFS.Hiv ...
- 【转帖】nginx变量使用方法详解-7
https://www.diewufeiyang.com/post/581.html 在 (一) 中我们提到过,Nginx 变量的值只有一种类型,那就是字符串,但是变量也有可能压根就不存在有意义的 ...
- [转帖]kafka漏洞升级记录,基于SASL JAAS 配置和 SASL 协议,涉及版本3.4以下
攻击者可以使用基于 SASL JAAS 配置和 SASL 协议的任意 Kafka 客户端,在对 Kafka Connect worker 创建或修改连接器时,通过构造特殊的配置,进行 JNDI 注入. ...
- [转帖] Linux命令拾遗-网络抓包工具
https://www.cnblogs.com/codelogs/p/16060684.html 简介# Linux中有很多抓包工具,如ngrep.tcpdump与tshark等,它们有很多用法与使用 ...
- Bash 脚本发送消息到企业微信的办法
1. Study From https://www.cnblogs.com/elvi/p/11444388.html 2. 申请或者使用已经有的企业微信. 首先是获取一下企业id 方法如图: 3. 创 ...