运算符:__XADD
多核运算符是 IEC 61131-3 标准的扩展。
该运算符可用于实现原子计数器。如果一个整数变量通过普通加法的方式递增,例如 iTest := iTest + 1;
, 那么这个操作不是原子执行的。对变量的另一次访问可能发生在读取和写入变量之间。
如果计数器在多个任务中递增,则计数器结果可能小于计数周期数。因此,如果两个任务一次执行上述代码并且变量先前具有该值 0
, 然后变量可以有值 1
.如果在多个任务中处理数组并且在每个处理周期中都需要数组的唯一索引,则这尤其成问题。
当。。。的时候 __XADD
操作符被调用,它得到一个类型的指针 DINT
变量作为第一个被加数和类型 DINT
值作为第二个加法。 __XADD
返回第一个 summand 的旧值,并在同一步骤中将第二个 summand 添加到第一个 summand。
例如,函数调用可能如下所示: diOld := __XADD(ADR(diVar), deAdd);
例 156. 例子
下面的例子展示了一个典型的用法。一个数组应该由两个任务填充。在此过程中,应使用数组中的所有位置,并且不应覆盖任何位置。
使用此函数,多个任务可以填充一个布尔数组。
FUNCTION WriteToNextArrayPosition : BOOL VAR_EXTERNAL g_diIndex : DINT; // Index and array are globally defined and used by multiple tasks g_boolArray : ARRAY [0..1000] OF BOOL; END_VAR VAR_INPUT bToWrite : BOOL; END_VAR VAR diIndex : DWORD; END_VAR diIndex := __XADD(ADR(g_diIndex), 1); // Returns a unique index WriteToNextArrayPosition := FALSE; IF (diIndex >= 0 AND diIndex <= 1000) THEN g_boolArray[diIndex] := bToWrite; //Writes to unique index WriteToNextArrayPosition := TRUE; // TRUE: Array was not full yet END_IF